C++类模板

1.上期内容

C++模板函数

2.模板类

类模板是为了减少重复工作量而出现的一种进制,当一个类的功能类似只是类型不同时,一个通用的类模板可以根据使用者的需要而生成具体类型的类,从而减少功能重复的代码。

C++在STL中大量使用了类模板,很多迭代器与算法的实现都离不开泛型编程与类模板的支持。所以掌握类模板的基本使用是很重要的。

1.在类内部定义与声明

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T>
class DEMO {

public:
	DEMO(T data) {
		this->data = data;
	}

	~DEMO() {

	}

	int GetData() {
		return this->data;
	}

private:
	T data;
};


template <typename T,typename T1>
class DEMO1 {

public:
	DEMO1() {

	}

	~DEMO1();

private:
	T data;
	T1 ch;
};


int main(void) {

	DEMO<int> demo(5);           //显示的指定类型为int
	DEMO1<int, char> demo1();    //显示的指定类型分别为int,char
	cout << "data=" << demo.GetData() << endl;
	
	system("pause");

	return 0;
}

在这里插入图片描述

类模板的定义与使用使用的是和模板函数一样的关键字。即先声明template,在使用typename声明虚拟类型。

与模板函数不同的是,类模板不能被自动推导出类型,只能显示的指定具体的类型。如上面代码中的 DEMO< int > demo(5),该模板类被显示的指定为int型。

2.在类外部定义成员函数

在类内部声明成员函数,在类外部定义成员函数时,只要成员函数参数列表中出现了类限定域说明模板类作为返回类型模板类作为参数类型,那么就要在成员函数之前声明 template <类型形式参数表>,并且在模板类后加上虚拟参数列表

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T>
class DEMO {

public:
	DEMO(T data);
	~DEMO();
	DEMO operator+(int sum);
	int PrintData(DEMO& demo);

private:
	T data;
};


template<typename T>          //出现了类限定域说明
DEMO<T>::DEMO(T data)
{
	this->data = data;
}

template<typename T>         //出现了类限定域说明
DEMO<T>::~DEMO()
{
}

template<typename T>                //出现了作为返回值类型的模板类类型
DEMO<T> DEMO<T>::operator+(int sum)
{
	return *this;
}

template<typename T>               //出现了作为参数类型的模板类类型
int DEMO<T>::PrintData(DEMO<T>& demo)
{
	cout << "data=" << demo.data << endl;
	return 0;
}


int main(void) {

	DEMO<int> demo(5), demo1(15);
	demo.PrintData(demo1);
	demo + 5;

	system("pause");

	return 0;
}

在这里插入图片描述

DEMO< T >中的< T >是虚拟参数列表。

总结来说,只要看到了模板类的类名关键字出现在成员函数参数列表中,就要在成员函数之前声明 template <类型形式参数表>,并且在模板类类名后加上虚拟参数列表

3.模板类的继承

分为三种情况。一:子类是模板类,父类是普通类;二:父类是模板类,子类是普通类;三:父类与子类都是模板类。其中第一种情况与两个普通类的继承是一样的。就不说了。

1.父类是模板类,子类是普通类:

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T>
class FATHER {

public:
	FATHER(T data) {
		this->data = data;
	}

	~FATHER() {

	}

private:
	T data;
};


class SON:public FATHER<int> {        //显示的指明父类的具体类型

public:
	SON(int data):FATHER<int>(data) {
		this->data = data;
	}

	~SON() {

	}

	int GetData() {
		return data;
	}

private:
	int data;
};

int main(void) {

	SON son(15);
	cout << "data=" << son.GetData() << endl;

	system("pause");

	return 0;
}

子类是一般类,父类是模板类,继承时必须在子类里实例化父类的类型参数。其实这很好理解,因为在子类对象构造之前,会先调用父类的构造函数,父类为模板类,要想实例化,需要有指定的类型。

2.父类与子类都是模板类:

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T>
class FATHER {

public:
	FATHER(T data) {
		this->data = data;
	}

	~FATHER() {

	}

private:
	T data;
};


template <typename T1>
class SON:public FATHER<T1> {       //使用子类的模板类型传递到父类中,也可以使用具体的类型

public:
	SON(int data):FATHER<int>(data) {
		this->data = data;
	}

	~SON() {

	}

	int GetData() {
		return data;
	}

private:
	T1 data;
};

int main(void) {

	SON<int> son(15);
	cout << "data=" << son.GetData() << endl;

	system("pause");

	return 0;
}

在这里插入图片描述

当子类与父类都是模板类时,继承时也必须在子类里实例化父类的类型参数,值得注意的是,此时实例化的类型参数可以使用子类的模板类型。即让父类与子类在实例化后拥有一样的具体类型。当然也可以使用其它的具体类型。

4.模板类与static数据成员

类的static数据成员需在类内定义,在类外初始化。

对于普通类,各个对象之间共享同一个static变量。而模板类使用不同类型实例化后生成的其实是不同的类(虽然类名一样,但在编译器内部其实是采用不同的标识),它们各自拥有不同的static数据成员。因此它们实例化后的对象使用的也是不同的static成员。

看一个例子:

#include <iostream>
#include <stdio.h>

using namespace std;

template <typename T>
class DEMO {

public:
	DEMO(int mask) {
		this->mask = mask;
	}

	~DEMO() {
	}

	static int data;

private:
	int mask;
	T tmp;
};

template <typename T>      //初始化static数据成员
int DEMO<T>::data = 0;


int main(void) {

	DEMO<int> demo(0), demo1(1);
	DEMO<char> demo2(2), demo3(3);
	cout << "被修改后前demo的data的值:" << demo.data << endl;
	cout << "被修改后前demo1的data的值:" << demo1.data << endl;
	cout << "被修改后前demo2的data的值:" << demo2.data << endl;
	cout << "被修改后前demo3的data的值:" << demo3.data << endl;
	cout << endl;

	demo.data = 555;
	demo2.data = 666;

	cout << "被修改后的demo的data的值:" << demo.data << endl;
	cout << "被修改后的demo1的data的值:" << demo1.data << endl;
	cout << "被修改后的demo2的data的值:" << demo2.data << endl;
	cout << "被修改后的demo3的data的值:" << demo3.data << endl;


	system("pause");

	return 0;
}

在这里插入图片描述

3.使用模板类实现vector容器

设计一个vector容器,可以储存int,char ,float,double等基础类型。可以使用[]访问容器中元素,支持两个容器之间的直接赋值,支持用一个容器构造另一个容器。

可以先自己思考,答案我放在另一篇博客。

模板类实现vector容器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值