C++模板 — 类模板

请先阅览函数模板相关内容:C++模板 — 函数模板

类模板的定义

1、格式与写法:

template < class类型参数1, class类型参数2, ...>
class 类模板名
{
    成员函数和成员变量
};

2、如果在类外定义成员函数,若此成员函数中有模板参数存在,则除了需要和一般类的类外定义成员函数一样的定义外,还需要在函数外进行模板声明:

template <类型参数表>
返回值类型  类模板名<类型参数名列表>::成员函数名(参数表)
{
    ...
}

3、用类模板定义对象的写法如下:

类模板名<真实类型参数表> 对象名(构造函数实际参数表);

4、如果类模板有无参构造函数,那么也可以使用如下写法创建对象:

类模板名 <真实类型参数表> 对象名;

第一个类模板程序:

#include<iostream>
using namespace std;
//定义类模板
template<class T1,class T2>
class Ha
{
public:
	Ha(T1 _t1, T2 _t2);
	void show();

private:
	T1 t1;
	T2 t2;
};

//类模板的类模板函数的类外定义
template<class T1,class T2>
Ha<T1,T2>::Ha(T1 _t1, T2 _t2)
{
	t1 = _t1;
	t2 = _t2;
}

//类模板的普通函数类外定义
template<class T1, class T2>
void Ha<T1,T2>::show()
{
	T1 tt = t1;
	cout << "t1=" << t1 << ",t2=" << t2 << endl;
}

int main()
{
	Ha<int, int> aa(1,2);
	aa.show();

	system("pause");
	return 0;
}

类模板特性

1. 类模板和函数模板的区别

  •  类模板没有自动类型推导的使用方式
  • 类模板在模板参数列表中可以有默认参数

点击查看实现代码

2. 类模板中成员函数和普通类中成员函数创建时机有区别

  • 普通类中的成员函数一开始就可以创建
  • 类模板中的成员函数在调用时才创建

点击查看实现代码:

3. 类模板对象作为函数参数

类模板对象一共有三种传入方式:

  1. 指定传入的类型   --- 直接显示对象的数据类型【最常用】
  2. 参数模板化    --- 将对象中的参数变为模板进行传递
  3. 整个类模板化   --- 将这个对象类型 模板化进行传递

点击查看实现代码:

类模板与继承

相关规则:

  1. 当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中T的类型
  2. 如果不指定,编译器无法给子类分配内存
  3. 如果想灵活指定出父类中T的类型,子类也需变为类模板
template <class T1, class T2> //类模板
class A
{
	Tl v1; T2 v2;
};

template <class T1, class T2>
class B : public A <T2, T1> //错误写法:“class B:public A”;因为必须知道父类中的T类型才能继承给子类
{
	T1 v3; T2 v4;
};

template <class T>
class C : public B <T, T>
{
	T v5;
};

int main()
{
	B<int, double> obj1;
	C<int> obj2;
	return 0;
}

当编译到main函数中的第一个语句:“B<int, double> obj1;”,编译器用 int 替换类模板 B 中的 T1,用 double 替换 T2,生成 B<int, double> 类如下:

class B <int, double>: public A <double, int>
{
     int v3; double v4;
};

B <int, double> 的基类是 A <double, int>。于是编译器就要用 double 替换类模板 A 中的 T1,用 int 替换 T2,生成 A<double, int> 类如下:

class A <double, int>
{
    double v1; int v2;
};

 

 

类模板中的静态成员

类模板中可以定义静态成员,从该类模板实例化得到的所有类都包含同样的静态成员

#include <iostream>
using namespace std;

template <class T>
class A
{
private:
	static int count;
public:
	A() { count++; }
	~A() { count--; };
	A(A &) { count++; }
	static void PrintCount() { cout << count << endl; }
};

template<> int A<int>::count = 0;
template<> int A<double>::count = 0;

int main()
{
	A<int> ia;
	A<double> da;
	ia.PrintCount();
	da.PrintCount();
	return 0;
}

 

注:部分源代码和阐述出自“黑马程序员相关课程”!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值