目录
一、模板类的继承
1、模板类继承的多种情况(常见的)
类模板:不确定的类,类中用到了模板
模板类:确定的类,类中用到了模板
(1)类模板 继承 类模板
(2)类模板 继承 模板类
(3)类模板 继承 普通类
(4)普通类 继承 模板类
2、类模板继承类模板
(1)单模板参数,类模板继承类模板
(2)代码实战中学习
#include <iostream>
using namespace std;
template <typename T> class People
{
private:
T attribute;
public:
People(){};
People(T my_attitude):attribute(my_attitude){};
void print(void);
};
template <typename T> void People<T>::print(void)
{
cout << "attribute = " << this->attribute << endl;
}
template <typename U> class Man: public People<U>
{
private:
U P_attribute;
public:
Man(){};
Man(U a, U b):People<U>(a),P_attribute(b){};
void Man_print(void);
};
template <typename U> void Man<U>::Man_print(void)
{
cout << "P_attribute = " << this->P_attribute << endl;
}
int main(int argc, char *argv[])
{
Man<string> s("sdsd", "dsds");
s.print();
s.Man_print();
return 0;
}
(3)总结:在继承时,相当于用子类的模板参数U去实例填充了父类的模板参数T
(4)作用:用于构建模板化的类体系,写模板化的大框架
3、多模板参数
(1)2个或2个以上模板参数的情况
(2)代码实战中学习
#include <iostream>
using namespace std;
template <typename T1, typename T2> class People
{
private:
T1 attribute1;
T2 attribute2;
public:
People(){};
People(T1 my_attitude1, T2 my_attitude2):attribute1(my_attitude1),attribute2(my_attitude2){};
void print(void);
};
template <typename T1, typename T2> void People<T1, T2>::print(void)
{
cout << "attribute1 = " << this->attribute1 << endl;
cout << "attribute2 = " << this->attribute2 << endl;
}
template <typename U1, typename U2> class Man: public People<U1, U2>
{
private:
U1 P_attribute1;
U2 P_attribute2;
public:
Man(){};
Man(U1 a, U2 b, U1 a1, U2 a2):People<U1, U2>(a, b),P_attribute1(a1),P_attribute2(a2){};
void Man_print(void);
};
template <typename U1, typename U2> void Man<U1, U2>::Man_print(void)
{
cout << "P_attribute1 = " << this->P_attribute1 << endl;
cout << "P_attribute2 = " << this->P_attribute2 << endl;
}
int main(int argc, char *argv[])
{
Man<string, int> s("sdsd", 18, "dsds", 20);
s.print();
s.Man_print();
return 0;
}
(3)注意:多个模板参数是按照顺序对应的
4、类模板 继承 模板类
#include <iostream>
using namespace std;
template <typename T> class People
{
private:
T attribute;
public:
People(){};
People(T my_attitude):attribute(my_attitude){};
void print(void);
};
template <typename T> void People<T>::print(void)
{
cout << "attribute = " << this->attribute << endl;
}
template <typename U> class Man: public People<double>//在这里将People类确定为double
{
private:
U P_attribute;
public:
Man(){};
Man(double a, U b):People<double>(a),P_attribute(b){};//这里的a的类型也由此确定了
void Man_print(void);
};
template <typename U> void Man<U>::Man_print(void)
{
cout << "P_attribute = " << this->P_attribute << endl;
}
int main(int argc, char *argv[])
{
Man<string> s(6.666,"asdasd");
s.print();
s.Man_print();
return 0;
}
5、类模板 继承 普通类
#include <iostream>
using namespace std;
class People
{
private:
double attribute;
public:
People(){};
People(double my_attitude):attribute(my_attitude){};
void print(void);
};
void People::print(void)
{
cout << "attribute = " << this->attribute << endl;
}
template <typename U> class Man: public People//
{
private:
U P_attribute;
public:
Man(){};
Man(double a, U b):People(a),P_attribute(b){};//
void Man_print(void);
};
template <typename U> void Man<U>::Man_print(void)
{
cout << "P_attribute = " << this->P_attribute << endl;
}
int main(int argc, char *argv[])
{
Man<string> s(6.666,"asdasd");
s.print();
s.Man_print();
return 0;
}
6、普通类 继承 模板类
#include <iostream>
using namespace std;
template <typename T> class People
{
private:
T attribute;
public:
People(){};
People(T my_attitude):attribute(my_attitude){};
void print(void);
};
template <typename T> void People<T>::print(void)
{
cout << "attribute = " << this->attribute << endl;
}
class Man: public People<double>//在这里将People类确定为double
{
private:
string P_attribute;
public:
Man(){};
Man(double a, string b):People<double>(a),P_attribute(b){};//这里的a的类型也由此确定了
void Man_print(void);
};
void Man::Man_print(void)
{
cout << "P_attribute = " << this->P_attribute << endl;
}
int main(int argc, char *argv[])
{
Man s(6.666,"asdasdsdfsdfoo");
s.print();
s.Man_print();
return 0;
}
二、非类型模板参数和模板类型推导
1、非类型模版参数
详解阅读:参考 https://blog.csdn.net/lanchunhui/article/details/49634077
template<typename T, int MAXSIZE>
{
T elems[MAXSIZE];
}
int main(void)
{
Stack<int, 10> int10Stack;
return 0;
}
非类型模板参数是有类型限制的。一般而言,它可以是常整数(包括enum枚举类型)或者指向外部链接对象的指针。
2、模板的本质
参数化:将其作为参数一样,通过传参确定
(1)类型参数化
(2)值参数化
(3)类型和值都参数化
(4)本质:延迟绑定
3、类型推导的隐式类型转换
(1)在决定模板参数类型前,编译器执行隐式类型转换,有时候实际类型和看起来会不同
(2)编译器用值类型实例化函数模板,而不是用相应的引用类型
(3)编译器用指针类型实例化函数模板,而不是相应的数组类型
(4)去除const修饰,绝不会用const类型实例化函数模板,总是用相应的非const类型
(5)对于指针来说,指针和 const 指针是不同的类型。
(2)
int a = 5;
int &b = a;
People<b>//实例化时会将int& 转换为 int
(3)
int a[5];
void func(a); // 数组做实参,实际实参不是数组而是指针
People<a>
(4)
const int a = 5;
People<a>//实例化时会去除const
(5)
const int *p1;
int *p2;
4、模板和库
(1)模板无法单独编译,也就不能通过lib连接静态库的形式隐藏实现
(2)模板通常会把声明和定义写在头文件里,所以c++的模板总是开源的
(3)说明typename的一种用法,这种用法里typename不等同于class
详解阅读:https://www.cnblogs.com/cthon/p/9201649.html
注:本文章参考了《朱老师物联网大讲堂》课程笔记,并结合了自己的实际开发经历以及网上他人的技术文章,综合整理得到。如有侵权,联系删除!水平有限,欢迎各位在评论区交流。