C++类模板

本文详细介绍了C++中的类模板,包括其基本概念、模板参数的使用、类模板与函数模板的区别、类模板继承、友元以及在分文件编写中的处理方法。

C++中的类模板是一种通用的类定义,它可以用于创建可以适应不同类型的对象。类模板是一种参数化的类,它可以根据不同的模板参数创建多个具体的类。

类模板的定义包含一个或多个模板参数,这些参数可以用于指定类中的类型、常量或其他模板参数。在使用类模板时,我们需要提供实际的模板参数,这些参数将用于实例化具体的类。

类模板语法

template<typename T>
类
  • template --- 声明创建模板

  • typename --- 表面后面的符号其实是一种数据类型,可以用class代替

  • T 通用数据类型,名称可以替换,一般都用T

template<class NameType,class AgeType> 
class Person{
public:
    Person(NameType name,AgeType age){
        this->name = name;
        this->age = age;
    }
    void showPerson(){
        cout << "name:" << this.name << "age:" << this.age << endl;
    }
    NameType name;
    AgeType age;
}
​
void test(){
    Person<string,int> p1("tang",20);
    p1.showPerson();
}

类模板和函数模板区别

  • 类模板没有自动类型推导使用方式

  • 类模板在模板参数列表中可以有默认参数,而函数模板不行

Person p1("tang",20); //报错,无自动类型推导
Person<string,int> p1("tang",20); //正确
//定义时给默认参数
template<class NameType,class AgeType = int> 
Person p1<string>("tang",20); //不报错,后面默认当作int类型

类模板中的成员函数并不是一开始就创建,而是调用时才去创建,这在分文件编写时就显得很关键

类模板对象做函数参数

类模板参数对象做函数参数有三种形式:

我先定义一个类模板

template<class T1,class T2> 
class Person{
public:
    Person(T1 name,T2 age){
        this->name = name;
        this->age = age;
    }
    void show(){
        cout << "name:" << this.name << "age:" << this.age << endl;
    }
    T1 name;
    T2 age;
};
​
void test(){
 Person<string,int> p('tang',20);
 showPerson(p);
}
  • 指定传入类型 使用比较广泛

void showPerson(Person<string,name> &p){
    p.show();
}
  • 参数模板化

template<class T1,class T2>
void showPerson(Person<T1,T2>& p){
    p.show();
}
  • 整个类都模板化

template<class T>
void showPerson(T &p){ //让他自己推导
    p.show();
}

类模板与继承

  • 当子类继承的父类是一个类模板时,子类在声明的时候要指定出父类中T的类型

  • 如果不指定,编译器无法给子类分配内存

  • 如果想灵活指定父类T的类型,子类也要变成类模板

template<class T>
class Base{
public:
    T a;
};
​
//C++编译器要给子类分配内存,必须知道父类中T的类型才能分配并向下继承
class Son:public Base<int>{ //必须指定一个类型,否则无法继承
public:
    
};
​
//或者也变成模板
template<class T1,class T2>
class Son2:public Base<T2>{ //T2为继承的,T1是自己的
    T1 obj;
};
Son2<int,char> S2;

类模板成员函数类外实现

template<class T1,class T2>
class Person{
public:
    T1 name;
    T2 age;
    Person(T1 name,T2 age);
    void show();
};
//构造函数类外实现
template<class T1,class T2>
Person<T1,T2>::Person(T1 name,T2 age){
    this->name = name;
    this->age = age;
}
//成员函数类外实现
template<class T1,class T2>
Person<T1,T2>::show(){
    cout << "name:" << this.name << "age:" << this.age << endl;
}

类模板份文件编写

  • 第一种解决办法,直接包含源文件

  • 第二种解决办法将.h和.cpp内容写到一起并将后缀名改为.hpp文件

一般使用第二种

类模板与友元

一般使用类内实现,类外实现形式比较复杂

//对于全局函数类外实现,还需要加前置声明才能让编译器知道。。。
template<class T1,class T2>
class Person;
//函数实现也得放在友元定义之前
template<class T1,class T2>
void printPerson2(Person<T1,T2> p){
    cout << this.name << this.age << endl;
}
​
template<class T1,class T2>
class Person{
//全局函数类内实现
friend void printPerson(Person<T1,T2> p){
    cout << this.name << this.age << endl;
}
friend void printPerson2<>(Person<T1,T2> p); //全局函数类外实现,在类内声明为友元函数
//必须加一个空参数列表,才能和外面函数模板一致,否则这里定义的就是一个普通函数而不是函数模板
private:
    T1 name;
    T2 age;
public:
    Person(T1 name,T2 age){
        this->name = name;
        this->age = age;
    }
};
​

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值