C++学习笔记(七) 模板(二) 类模板

1. 类模板

1.1 类模板基本语法

类模板需要自己传入类型参数,不能自动推导,并且模板的参数列表可以有默认参数。

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

template<typename AGETYPE,typename NAMETYPE = string>	/* 尖括号是模板的参数列表 */
class Person
{
public:
	Person(AGETYPE age, NAMETYPE name)
	{
		this->age_ = age;
		this->name_ = name;
	}

	AGETYPE age_;
	NAMETYPE name_;
};

void test_1(void)
{
	// Person p1(18,"lagransun"); 				/* 类模板没有自动类型推导的使用方式 */
	Person <int>p1(18,"lagransun"); 			/* 相当于把int给了AGETYPE,NAMETYPE默认参数是string,如果传参的话就变成你传进去的类型 */
	cout << p1.age_ << " " << p1.name_ << endl;
}

int main(void)
{
	test_1();
	return 0;
}

代码运行结果如下
在这里插入图片描述

1.2 类模板中成员函数的创建时机

普通的类中的成员函数在开始时就创建,类模板中的成员函数调用是才会创建。所以,按理说下面代码是可行的,虽然不知道Person中的成员变量p_是否能调用PrintPerson1()或者PrintPerson2(),但是编译器并不会报错,因为func1()func2()是调用的时候才创建的。

但是很可惜,跟我理解的不一样,报错了。

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

class Person1
{
public:
	void PrintPerson1(void)
	{
		cout << "Person1" << endl;
	}
};

class Person2
{
public:
	void PrintPerson2(void)
	{
		cout << "Person2" << endl;
	}
};

template<typename TYPE>	/* 尖括号是模板的参数列表 */
class Person
{
public:

	TYPE p_;

	void func1()
	{
		p_.PrintPerson1();
	}

	void func2()
	{
		p_.PrintPerson2();
	}
};

template<typename TYPE>	
void test_2(TYPE p)
{
	if(typeid(p.p_) == typeid(Person1)) p.func1();
	else if (typeid(p.p_) == typeid(Person2)) p.func2();
	else printf("都不是");
}

void test_1(void)
{
	Person <Person1>p; 			/* 相当于把int给了AGETYPE,NAMETYPE默认参数是string,如果传参的话就变成你传进去的类型 */
	test_2(p);
}

int main(void)
{
	test_1();
	return 0;
}

修改test_2(),注释掉p.func2(),可以编译

template<typename TYPE>	
void test_2(TYPE p)
{
	if(typeid(p.p_) == typeid(Person1)) p.func1();
	// else if (typeid(p.p_) == typeid(Person2)) p.func2();  /* 报错 */
	else printf("都不是");
}

看来是编译阶段调用的时候就会创建这个函数了。代码运行结果如下
在这里插入图片描述

1.3 类模板与继承

如果要以类模板为父类进行继承,那么子类有两种继承方式:

  1. 继承的时候传入父类类模板的参数
  2. 将要继承的子类也写成类模板
#include <iostream>
#include <string>
using namespace std;


template<typename TYPE>	/* 尖括号是模板的参数列表 */
class Person
{
public:
	TYPE var_l;
};

class PersonTest1 : public Person<int> /* 继承的时候需要传入模板的参数 */
{
public:
	void Func()
	{
		cout << "成功继承:" << var_l << endl;
	}
};

template<typename TYPE1, typename TYPE2>	/* 或者继承的类也弄成类模板 */
class PersonTest2 : public Person<TYPE1>
{
public:
	TYPE1 var_l;
	void Func()
	{
		cout << "成功继承:" << var_l << endl;
	}

};

void test_1(void)
{
	PersonTest1 pt;
	PersonTest2<int,int> pt2;
	pt1.Func();
	pt2.Func();
}

int main(void)
{
	test_1();
	return 0;
}

代码运行结果如下
在这里插入图片描述

1.4 类模板成员函数的类外实现

类模板成员函数的类外实现,与普通成员函数的区别就是说明作用域的同时要传入类型(尖括号)

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


template<typename TYPE1, typename TYPE2>	/* 尖括号是模板的参数列表 */
class Person
{
public:
	Person(TYPE1 age, TYPE2 name)
	{
		age_ = age;
		name_ = name;
	}

	void PrintMember();
	TYPE1 age_;
	TYPE2 name_;
};

template<typename TYPE1, typename TYPE2>	/* 类模板成员函数的类外实现,与普通成员函数的区别就是说明作用域的同时要传入类型(尖括号) */
void Person<TYPE1, TYPE2> ::PrintMember()
{
	cout << "类模板成员函数的类外实现: " << age_ << " " << name_ << endl;
}


void test_1(void)
{
	Person<int ,string> p1(18,"lagransun");
	p1.PrintMember();
}

int main(void)
{
	test_1();
	return 0;
}

代码运行结果如下
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值