C++类模板常见用途和注意实现
Posted Ang_qq_252390816
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++类模板常见用途和注意实现相关的知识,希望对你有一定的参考价值。
类模板定义
template<class T1,class T2 > //模板参数可以有一个或者多个
class 类名 ;
类模板和函数模板的区别
1,类模板不能自动类型推导,需要显示的指定类型;函数模板可以自动类型推导;
2,类模板在模板参数列表中可以有默认参数;函数模板中不能使用默认参数
#include<iostream>
using namespace std;
//类模板
template<class T1,class T2>
class Student
public :
T1 name;
T2 age;
Student(T1 name, T2 age)
this->name = name;
this->age = age;
void show()
cout << name << age << "岁了"<<endl;
;
//类模板中的模板参数列表可以指定默认参数.例如为模板参数T2设置默认参数int
template<class T1, class T2 =int>
class Student2
public:
T1 name;
T2 age;
Student2(T1 name, T2 age)
this->name = name;
this->age = age;
void show()
cout << name << age << "岁了" << endl;
;
void test1()
Student<string, int> s("王阳明", 100);//类模板必须显示的指定模板类型,不会隐式转换;
s.show();
void test2() //类模板中模板参数列表中设置了默认参数,使用类模板时不用再指定参数类型
Student2<string> s("韩非子", 1001);
s.show();
int main()
test1();
test2();
system("pause");
return 1;
类模板成员函数的创建时机
类模板中的成员函数只有在调用的时候才会创建;但是普通类中的成员函数一开始就可以创建;
使用代码验证
#include<iostream>
using namespace std;
class Student1
public:
void showMsg1()
cout << "我是Student1" << endl;
;
class Student2
public:
void showMsg2()
cout << "我是Student2" << endl;
;
template<class T>
class Test
public:
T obj;
void showS1()
obj.showMsg1();
void showS2()
obj.showMsg2();
;
int main()
Test<Student1> t;//如果不调用Test中的成员函数,可以编译通过,也就是验证了,类模板成员函数是在调用时创建;不调用不创建;
t.showS1(); //到这里程序也能运行起来
//t.showS2(); //如果调用成员函数showS2()就要报错,因为Student1中没有成员函数showS2();如果不调用showS2()程序就没问题,进一步说明类模板的成员函数再调用时才创建;
return 1;
类模板作为函数参数
类模板最为函数参数有三种实现方式如下:
1,指定传入类型
//类模板最为函数参数三种方式发
//1,指定传入类型,指明类模板中模板参数具体类型;
void printStudent1(Student& s) //注意变量为引用数据类型
s.show();
//类模板作为参数的函数调用
void test1()
Student s("小米", 4);
printStudent1(s);
2,参数模板化
//2,参数模板化,把类模板中模板参数模板化,不指定具体类型;其实就是函数模板加类模板的结合使用
template<typename T1,typename T2>
void printStudent2(Student<T1, T2>&s) //注意变量为引用数据类型
s.show();
void test2()
Student<string, int > s("小艾", 5);
printStudent2(s);
3,整个类模板化
//3,整个类模板化,把类作为一个模板,
template<typename T>
void printStudent3(T& s) //注意变量为引用数据类型
s.show();
void test3()
Student s("小明", 3);
printStudent3(s);
这个源文件如下:常用的还是第一种,比较直观,容易理解代码可读性强;
#include<iostream>
using namespace std;
template <typename T1,typename T2>
class Student
public :
string name;
int age;
Student(T1 t1, T2 t2)
this->name = t1;
this->age = t2;
void show()
cout << name << "同学今年" << age << "岁" << endl;
;
//类模板最为函数参数三种方式发
//1,指定传入类型,指明类模板中模板参数具体类型;
void printStudent1(Student<string, int>& s) //注意变量为引用数据类型
s.show();
//类模板作为参数的函数调用
void test1()
Student<string, int > s("小米", 4);
printStudent1(s);
//2,参数模板化,把类模板中模板参数模板化,不指定具体类型;其实就是函数模板加类模板的结合使用
template<typename T1,typename T2>
void printStudent2(Student<T1, T2>&s) //注意变量为引用数据类型
s.show();
void test2()
Student<string, int > s("小艾", 5);
printStudent2(s);
//3,整个类模板化,把类作为一个模板,
template<typename T>
void printStudent3(T& s) //注意变量为引用数据类型
s.show();
void test3()
Student<string, int > s("小明", 3);
printStudent3(s);
int main()
test1();
test2();
test3();
return 1;
类模板最为函数参数,调用这个函数的方式都一样;
类模板继承
#include<iostream>
using namespace std;
template<class T>
class Animal
public:
T type;
Animal()
cout << "T的类型:" << typeid(T).name() << endl;
;
//类模板中的继承,需要制定父类模板参数的具体类型;语法规定
class Dog :public Animal<int>
;
//不指定具体类型也可以,把子类也变为类模板,传模板参数到父类;这样在子类中也可以动态的指定父类的模板参数类型,可变的;具体如下
template<class T1,class T2>
class Cat :public Animal<T2>
public:
T1 name;
void show() //可以通过系统函数typeid()查看以下父类的T和子类的T1函数调用时传入的具体类型
cout << "T1的类型:" << typeid(T1).name() << endl;
cout << "T2的类型:" << typeid(T2).name() << endl;
//cout << "T的类型:" << typeid(T).name() << endl; //注意T是父类的模板参数,这里不能判断是其类型,不然会报T未声明;
;
int main()
Cat<string, int> cat;
cat.show();
return 1;
类模板的成员函数,类外实现
具体解释看代码及注释,很详细
#include<iostream>
using namespace std;
template<class T>
class Animal
public:
T name;
Animal(T name);
/*
cout << "T的类型:" << typeid(T).name() << endl;
*/
void show();//成员函数声明
/*
cout << "动物名字:" << name << endl;
*/
;
//成员函数类外实现:1,复制成员函数的声明;2,去掉“;”加上 3,添加作用域(Animal::);
template<typename T>//标识为模板
Animal<T>::Animal(T name)//<T>用于区分和其他模板函数的不同
this->name = name;
template<typename T>
void Animal<T>::show() // Animal<T>后面的<T>用于标识为类模板的成员函数;
cout << "动物名字叫:" << name << endl;
int main()
Animal<string> a("小狗钱钱");
a.show();
return 1;
类模板分文件编写
类的模板函数的成员函数类外实现的分文件编写,即把声明部分写道Animal.h的头文件中;具体代码如下:
新建头文件Animal.h
#pragma once
#include<iostream>
using namespace std;
template<class T>
class Animal
public:
T name;
Animal(T name);
void show();//成员函数声明
;
Animal.cpp源文件中代码如下:
#include "Animal.h" //引入自定义的文件名使用""号
//成员函数类外实现:1,复制成员函数的声明;2,去掉“;”加上 3,添加作用域(Animal::);
template<typename T>//标识为模板
Animal<T>::Animal(T name)//<T>用于区分和其他模板函数的不同
this->name = name;
template<typename T>
void Animal<T>::show() // Animal<T>后面的<T>用于标识为类模板的成员函数;
cout << "动物名字叫:" << name << endl;
测试类
Test.cpp
#include "Animal.cpp" //注意是导入的.cpp文件也就是源码文件,一般不会这样写,不然相当于把源码暴露给别人了;
int main()
Animal<string> a("小狗钱钱");
a.show();
return 1;
类模板的分文件编写第二种方法,把函数声明和实现都写在.hpp文件中;.hpp文件和头文件放在一起,是约定的一个文件格式不是固定的;具体如下
Animal.hpp
#include<iostream>
using namespace std;
template<class T>
class Animal
public:
T name;
Animal(T name);
void show();//成员函数声明
;
//成员函数类外实现:1,复制成员函数的声明;2,去掉“;”加上 3,添加作用域(Animal::);
template<typename T>//标识为模板
Animal<T>::Animal(T name)//<T>用于区分和其他模板函数的不同
this->name = name;
template<typename T>
void Animal<T>::show() // Animal<T>后面的<T>用于标识为类模板的成员函数;
cout << "动物名字叫:" << name << endl;
Test.cpp文件中直接引入Animal.hpp文件即可调用;
类模板和友元
全局函数做友元类内实现,比较方便;但是如果类外实现需要先让编译器知道友元函数
#include<iostream>
using namespace std;
template<typename T1, class T2>
class Student;
//全局函数做友元,类外实现
template<class T1,class T2>
void showStudent2(Student<T1, T2> s)//这里用到Student类所以再次函数之前要先声明;
s.print();//友元函数可以访问类中的私有成员方法和成员属性
template<typename T1,class T2>
class Student
//全局函数做友元,类内实现
friend void showStudent(Student<string, int> s) //可以把模板参数列表换成T1,T2;
s.print();//友元函数可以访问类中的私有成员方法和成员属性
//全局函数做友元,类外实现 ,需要注意类外实现首先要告诉编译器,所以要在Student类之前实现showStudent2函数
friend void showStudent2<>(Student<T1, T2> s);//注意需要加空模板参数列表<>
private:
T1 name;
T2 age;
void print()
cout << "这位学生叫" << name << age << "岁了" << endl;
public:
Student(T1 name, T2 age)
this->name = name;
this->age = age;
;
int main()
Student<string,int> s("小度", 5);
showStudent(s);
Student<string, int> s2("小宝", 3);
showStudent2(s2);
return 1;
本文重点都在代码里面,注释很多,以免看不懂;
以上是关于C++类模板常见用途和注意实现的主要内容,如果未能解决你的问题,请参考以下文章