C++ 类模板

发布于:2024-05-07 ⋅ 阅读:(27) ⋅ 点赞:(0)

一、类模板的定义

类模板是C++中一种特殊的模板,用于创建通用的类。通过类模板,我们可以定义一个通用的类,这个类可以接受不同类型的数据作为其成员或参数。在使用类模板时,我们需要指定具体的数据类型,编译器会根据指定的数据类型生成对应的类。

作用:建立一个通用类,类中的成员的数据类型是不指定的(不具体),用一个或者多个虚拟的类型来表达

二、类模板操作

语法

三、类模板和模板函数的区别

1、类模板只能显示指定类型的方式,而函数模板有自动类型推导的方式。

2、类模板中的模板参数列表可以有默认的参数,而函数模板则没有。

注:有默认值的情况下可以不用显示实例化。

 代码示例:

#include <iostream>
using namespace std;

template <class NameType,class AgeType = int>//类型声明:不是类中有多少成员属性,看实际的类型种类
class Myclass{
    public:
        NameType name;
        AgeType age;
        Myclass(){}
        Myclass(NameType name,AgeType age):name{name},age{age}{}
        void print(){
            cout<<"name:"<<name<<",age:"<<age<<endl;
        }
};
int main()
{
    Myclass<string,int> mc("aaa",18);//必须使用显式指定类型的方式来使用类模板
    Myclass<string> mc1("bbb",15);//类模板中的模板参数列表可以指定默认参数
    mc.print();
    mc1.print();
    return 0;
}

运行结果:

name:aaa,age:18
name:bbb,age:15

 四、一般类模板的对象做函数参数有三种传入方式:

指定传入的类型:直接显示对象的数据类型

参数模板化:将对象中的参数变为模板进行传递(函数模板)。

整个类模板化:将这个对象的类型模板化进行传递(函数模板)。

#include <iostream>
using namespace std;

template <class NameType,class AgeType>
class Person{
    public:
        Person(){}
        Person(NameType name,AgeType age):name{name},age{age}{}
        NameType name;
        AgeType age;
        void printer()
        {
            cout<<"name:"<<name<<",age:"<<age<<endl;
        }
};
//直接显示对象的数据类型
void print1(Person<string,int>&p)
{
    p.printer();
}

//将对象中的参数变为模板进行传递(函数模板)
template<typename T1,typename T2>
void print2(Person<T1,T2>&p)
{
    p.printer();
}

//将这个对象的类型模板化进行传递函数模板
template<typename T>
void print3(T &p)
{
    p.printer();
}
int main()
{
    Person <string,int>p("gaoyinjie",27);
    print1(p);
    print2(p);
    print3(p);
    return 0;
}

运行结果:

name:gaoyinjie,age:27
name:gaoyinjie,age:27
name:gaoyinjie,age:27

 五、类模板继承

当子类继承父类是一个模板时,子类在声明时,需要指定父类中T的类型如果不指定,编译器就无法给子类分配内存,如果想灵活指定父类中T的类型,子类可以变为类模板

代码示例

#include <iostream>
using namespace std;

template<typename T>
class Base{
    public:
        T a;
};
//子类继承父类是一个模板时,子类在声明时需要指定父类中T的类型
class Son1:public Base<int>{
    public:
        Son1(){}
        Son1(int a):Base{a}{}
};
// 子类模板中T1替代(指定)父类模板中的T
template<class T1, class T2>
class Son2 : public Base<T1> {
public:
    T2 b;
};
int main()
{
    Son1 s1(3);
    cout<<s1.a<<endl;
    Son2 <int,string>s2;
    s2.a = 3;
    s2.b = "zhangsan";
    cout<<s2.a<<endl;
    cout<<s2.b<<endl;
    return 0;
}

 运行结果:

3
3
zhangsan

六、类模板和友元 

全局函数配合友元,类内实现(推荐)

template <class T1, class T2>
class Person{
    // 全局函数配合友元的类内实现
    friend void print(Person<T1,T2> & p){
        cout << "姓名:" << p.name << ",年龄:" << p.age << endl;
    }
    private:
        T1 name;
        T2 age;

    public:
        Person(T1 name, T2 age){
            this->name = name;
            this->age = age;
        }
};

int main(){
    Person<string,int> p("Jim",18);
    print(p);
    return 0;
}

七、类模板特化

完全特化:将模板参数列表中所有的参数都确定化。

偏特化:任何针对模板参数进一步进行条件限制设计的特化版本。

代码示例:

#include <iostream>
#include <string>
using namespace std;

template<typename T>
class Comparator{
    public:
        T a;
        T b;
        Comparator(T a,T b)
        {
            this->a = a;
            this->b = b;
        }
        T compare()
        {
            return a > b?a:b;
        }
};
template<>
class Comparator<string>{
    public:
        string a;
        string b;
        Comparator(string a,string b):a{a},b{b}{}
        string compare(){           //成员函数的实现应该和基础版的类模板不同
            return a.length()>b.length()?a:b;
        }
};
int main()
{
    Comparator<int> c1(12,13);
    cout<<"数的较大的值是:"<<c1.compare()<<endl;
    Comparator<string> c2("aaab","dfdf");
    cout<<"字符串更大的是:"<<c2.compare()<<endl;
    return 0;
}

运行结果:

数的较大的值是:13
字符串更大的是:dfdf