C++实验(三)——模板

C++实验(三)——模板,第1张

C++实验(三)——模板

目录

模板的概念

函数模板

类模板

实验

一、模板函数(compare)

一般模板函数

 特化模板函数

二、模板类Queue或Stack

queue.h

类模板的特化

模板成员函数特化

三、模板类AutoPtr


模板的概念

模板就是建立通用的模具,大大提高复用性

C++提供两种模板机制:函数模板和类模板

函数模板针对仅参数类型不同的函数;

类模板针对仅数据成员和成员函数类型不同的类。

函数模板
  • template 函数声明或定义

  • 使用函数模板有两种方式:自动类型推导、显示指定类型

类模板
  • 建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。
  • template

类模板与函数模板区别主要有两点:

  1. 类模板没有自动类型推导的使用方式
  2. 类模板在模板参数列表中可以有默认参数
实验 一、模板函数(compare) 一般模板函数
#include "mainwindow.h"
#include
#include 

template 
int compare(const Type &v1,const Type &v2)
{
    if(v1v2)
        return 1;
    return 0;
}
int main(int argc, char *argv[])
{
    const char *cp1="world",*cp2="hi";
    int a=1,b=2;
    compare(a,b);
    compare(cp1,cp2);
    return 0;
    
}

运行结果

 特化模板函数

当函数模板需要对某些类型进行特化处理,称为函数模板的特化。

template<>
int compare(const char * const &v1, const char * const &v2)
{
    cout<<"specialization"< 

运行结果

同时,函数模版的特化,当函数调用发现有特化后的匹配函数时,会优先调用特化的函数,而不再通过函数模版来进行实例化。

二、模板类Queue或Stack

类模板example

#include 
#include
using namespace std;
//类模板
template
class Person
{
public:
    Person(T1 name, T2 age)
    {
        this->mName = name;
        this->mAge = age;
    }
    void showPerson()
    {
        cout << "name: " << this->mName << " age: " << this->mAge << endl;
    }
public:
    T1 mName;
    T2 mAge;
};

//1、类模板没有自动类型推导的使用方式
void test1()
{
    Person p("xxd", 1000); //必须使用显示指定类型的方式,使用类模板
    p.showPerson();
}

//2、类模板在模板参数列表中可以有默认参数
void test2()
{
    Person  p("jmu", 999); //类模板中的模板参数列表 可以指定默认参数
    p.showPerson();
}

int main() {
    test1();
    test2();
    return 0;
}

类模板和函数模板语法相似,在声明模板template后面加类,此类称为类模板

运行结果

queue

  • push():会将一个元素置入queue中;
  • front():会返回queue内的第一个元素
  • back():会返回queue中的最后一个元素
  • pop():会移除queue内的第一个元素
     
queue.h
#ifndef QUEUE_H
#define QUEUE_H

#include 

using namespace std;


template class Queue; //先声明 Queue

template
class QueueItem{
    QueueItem(const Type &t):item(t),next(0){}
    Type item;
    QueueItem *next;
    friend class Queue;//友元函数 访问
    friend ostream& operator<<(ostream& os,const Queue &q); //运算符重载

    QueueItem* operator++(){
        return next;
    }
    Type & operator*(){
        return item;
    }
};

template
class Queue{
public:
    //定义构造器
    Queue():head(0),tail(0){}
    Queue(const Queue& q):head(),tail(){
        copy_items(q);
    }

    template
    Queue(It beg,It end):head(0),tail(0){
        copy_items(beg,end);
    }

    template void assign(It beg,It end);

    Queue& operator=(const Queue&);

    //析构函数
    ~Queue(){destory();}

    Type& front(){return head->item;}
    const Type& front() const {return head->item;}
    void push(const Type &);
    void pop();
    bool empty() const {
        return head==0;
    }

    friend ostream& operator<<(ostream& os,const Queue &q){
        os<<"< ";
        QueueItem *p;
        for(p=q.head;p;p=p->next){
            os<item<<" ";
        }
        os <<">";
        return os;
    }
    const QueueItem *Head() const{return head;}
    const QueueItem *End() const{return (tail==NULL)?NULL:tail->next ;}

private:
        QueueItem *head;
        QueueItem *tail;
        void destory();
        void copy_items(const Queue &);
        template void copy_items(It beg,It end);

};

//成员模板函数
template
void Queue::destory(){
        while(!empty()){
            pop();
        }
}

//移除第一个元素
template
void Queue::pop(){
    QueueItem* p=head;//赋值头指针
    head=head->next; //指向下一个指针
    delete p;
}

//在尾部添加一个新的元素
template 
void Queue::push(const Type& val){
    QueueItem *pt =new QueueItem(val);
    if(empty()){
        head=tail=pt;
    }
    else{
        tail->next=pt;
        tail=pt;
    }
}

//模板成员函数特化
template<>
void Queue::push(const char * const &val);

template<>
void Queue::pop();


template
void Queue::copy_items(const Queue &orig){
    for(QueueItem *pt = orig.head;pt;pt=pt->next){
        push(pt->item);
    }
}

template
Queue& Queue::operator=(const Queue& q)
{
    destory();
    copy_items(q);
}

template template void Queue::assign(It beg, It end)
{
    destory();
    copy_items(beg,end);
}

template template void Queue::copy_items(It beg,It end)
{
    while(beg!=end){
        push(*beg);
         ++beg;
    }
 }

template
int compare(const Type& v1, const Type& v2)
{
   if(v1v2) return 1;
   return 0;
}

template<>
int compare(const char * const &v1, const char * const &v2);


#endif // QUEUE_H
类模板的特化

当类模板内需要对某些类型进行特别处理时,使用类模板的特化。

模板成员函数特化

实现模板类Queue中的成员函数push()和pop()方法的特化版本,使其能够实现字符串的入队和出队 *** 作。

#include "Queue.h"
#include 
#include 
#include 
using namespace std;
template <>
void Queue::push( const char * const & str)
{
    char * pVal = new char[strlen(str)+1];
    strcpy(pVal,str);
    QueueItem * p = new QueueItem(pVal);
    if(empty())
    {
        head = tail = p;
    }
    else {
        tail->next = p;
        tail = p;
    }
}

template<>
void Queue::pop()
{
    if(empty())
    {
        return;
    }
    QueueItem * p = head;
    head = head->next;
    delete []p->item;
    delete p;
}


运行结果

三、模板类AutoPtr
#ifndef AUTOPTR_H
#define AUTOPTR_H
template 
class AutoPtr
{
public:

    AutoPtr(T* pData);
    AutoPtr(const AutoPtr& h);
    //调用析构函数
    ~AutoPtr();
    AutoPtr& operator=(const AutoPtr& h);
    void decrUser();

    T* operator ->() {
        return m_pData;
    }

    T& operator*() {
        return *m_pData;
    }
    const T& operator *() const {
        return *m_pData;
    }
    const T* operator -> () const {
        return m_pData;
    }
private:
    T* m_pData;
    int* m_nUser;
};
template < class T>
AutoPtr::AutoPtr(T* pData)
{
    m_pData = pData;
    //初始化用户数为1
    m_nUser = new int(1);
}
template < class T>
AutoPtr::AutoPtr(const AutoPtr& h) {
    m_pData = h.m_pData;
    m_nUser = h.m_nUser;

    (*m_nUser)++;
}
template < class T>
AutoPtr& AutoPtr::operator=(const AutoPtr& h)
{
    decrUser();
    m_pData = h.m_pData;
    m_nUser = h.m_nUser;
    (*m_nUser)++;
}
template < class T>
void AutoPtr::decrUser()
{
    --(*m_nUser);
    if ((*m_nUser) == 0) {

        delete m_pData;
        m_pData = 0;
        delete m_nUser;
        m_nUser = 0;
    }
}
template < class T>
AutoPtr::~AutoPtr()
{
    decrUser();
}
#endif // AUTOPTR_H

明天在写

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5504077.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-12
下一篇2022-12-12

发表评论

登录后才能评论

评论列表(0条)

    保存