马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
模板类的成员模板
结构体中可以有结构体,类中可以有类和成员函数。那么,模板类中也应该可以有模板类和模板函数。
在类AA中再创建一个模板类和模板函数。
先创建模板类,代码如下:
- #include <iostream>
- using namespace std;
- template <class T1, class T2>
- class AA {
- public:
- T1 m_x;
- T2 m_y;
- AA(const T1 x, const T2 y): m_x(x), m_y(y) {}
- void show() {cout << "AA的show ~ m_x = " << m_x << ", m_y = " << m_y << endl;}
- template <class T>
- class BB{
- public:
- T m_b;
- // 可以用AA的模板参数T1、T2创建成员变量
- T1 m_bx;
- BB() {}
- void show() {cout << "BB的show ~ m_b = " << m_b << ", m_bx = " << m_bx << endl;}
- };
- BB<string> bb; // 对象bb就是类模板AA的成员
- template <typename T> // 再创建一个函数模板,这个T和BB中的T没有关系
- void show(T t) {
- cout << "模板函数show ~ t = " << t << endl;
- cout << "AA ~ m_x = " << m_x << ", m_y = " << m_y << endl;
- bb.show();
- }
- };
- int main() {
- AA<int, string> aa(123, "你好");
- aa.show();
- aa.bb.m_b = "哈哈";
- aa.bb.m_bx = 666;
- aa.bb.show();
- aa.show<string> ("嘻嘻嘻");
- return 0;
- }
复制代码 运行效果如下:
AA的show ~ m_x = 123, m_y = 你好
BB的show ~ m_b = 哈哈, m_bx = 666
模板函数show ~ t = 嘻嘻嘻
AA ~ m_x = 123, m_y = 你好
BB的show ~ m_b = 哈哈, m_bx = 666
模板类中的成员模板,定义可以写在类的外面。修改后的代码如下:
- #include <iostream>
- using namespace std;
- template <class T1, class T2>
- class AA {
- public:
- T1 m_x;
- T2 m_y;
- AA(const T1 x, const T2 y): m_x(x), m_y(y) {}
- void show() {cout << "AA的show ~ m_x = " << m_x << ", m_y = " << m_y << endl;}
- template <class T>
- class BB{
- public:
- T m_b;
- // 可以用AA的模板参数T1、T2创建成员变量
- T1 m_bx;
- BB() {}
- void show();
- };
- BB<string> bb; // 对象bb就是类模板AA的成员
- template <typename T> // 再创建一个函数模板,这个T和BB中的T没有关系
- void show(T t);
- };
- // 模板类中的成员模板,定义可以写在类的外面。
- template <class T1, class T2>
- template <class T>
- void AA<T1, T2>::BB<T>::show() {
- {cout << "BB的show ~ m_b = " << m_b << ", m_bx = " << m_bx << endl;}
- }
- template <class T1, class T2>
- template <typename T>
- void AA<T1, T2>::show(T t) {
- cout << "模板函数show ~ t = " << t << endl;
- cout << "AA ~ m_x = " << m_x << ", m_y = " << m_y << endl;
- bb.show();
- }
- int main() {
- AA<int, string> aa(123, "你好");
- aa.show();
- aa.bb.m_b = "哈哈";
- aa.bb.m_bx = 666;
- aa.bb.show();
- aa.show<string> ("嘻嘻嘻");
- return 0;
- }
复制代码 运行效果跟之前保持同等:
AA的show ~ m_x = 123, m_y = 你好
BB的show ~ m_b = 哈哈, m_bx = 666
模板函数show ~ t = 嘻嘻嘻
AA ~ m_x = 123, m_y = 你好
BB的show ~ m_b = 哈哈, m_bx = 666
将模板类用作参数
C++的类模板主要是为了解决数据结构的问题。线性表有:链表、数组、栈、和队列。以链表和数组为例,为了支持任意类型数据,最好的方法就是用类模板来实现,代码如下:
- #include <iostream>
- using namespace std;
- template <class T, int len> // 实际上,链表没有长度的说法,但为了演示,假定有一个长度
- class LinkList {
- public:
- T* m_head; // 定义链表头节点指针
- int m_len = len; // 指定表长度
- // 链表常用操作
- void insert() {cout << "LinkList 插入操作" << endl;}
- void ddelete() {cout << "LinkList 删除操作" << endl;}
- void update() {cout << "LinkList 更新操作" << endl;}
- };
- template <class T, int len>
- class Array{
- public:
- T* m_data;
- int m_len = len;
- void insert() {cout << "Array 插入操作" << endl;}
- void ddelete() {cout << "Array 删除操作" << endl;}
- void update() {cout << "Array 更新操作" << endl;}
- };
- int main() {
- return 0;
- }
复制代码 模板的目的就是代码重用,既然链表和数组的逻辑结构是一样的,那就把它们改成模板类的形式。现在模板LinkList和Array,是为了兼容各种各样的数据类型,解决的是物理结构问题。接下来把它们再次模板化,是从逻辑角度来思量的。C++支持模板的模板,意思是把模板名当成一种特别的数据类型。实例化对象的时候,可以用模板签名作为参数,传给模板。示例代码如下:
- #include <iostream>
- using namespace std;
- template <class T, int len> // 实际上,链表没有长度的说法,但为了演示,假定有一个长度
- class LinkList {
- public:
- T* m_head; // 定义链表头节点指针
- int m_len = len; // 指定表长度
- // 链表常用操作
- void insert() {cout << "LinkList 插入操作" << endl;}
- void ddelete() {cout << "LinkList 删除操作" << endl;}
- void update() {cout << "LinkList 更新操作" << endl;}
- };
- template <class T, int len>
- class Array{
- public:
- T* m_data;
- int m_len = len;
- void insert() {cout << "Array 插入操作" << endl;}
- void ddelete() {cout << "Array 删除操作" << endl;}
- void update() {cout << "Array 更新操作" << endl;}
- };
- // 线性表模板类:其中,tabletype 表示 线性表类型,datatype 表示 线性表数据类型,len 表示 长度
- // tabletype 不是一个普通的参数,而是模板,意思是这个参数要填模板名。
- // 填什么样的模板名呢?填有两个参数的类模板名。并且,要求类模板的第一个参数是通用类型,第二个是非通用类型。
- // 此外,class可以用typename代替,只是class更直观。
- // tabletype只是一个模板名,用T1创建对象时,还需要指定具体的数据类型。
- // 常见的做法是:具体的数据类型用模板参数从外面传进来
- template<template<class, int>class tabletype, class datatype, int len> // 模板参数列表
- class LinearList{
- public:
- tabletype<datatype, len> m_table; // 创建线性表对象
- void insert() {m_table.insert();}
- void ddelete() {m_table.ddelete();}
- void update() {m_table.update();}
- };
- int main() {
- // 创建线性表对象,容器类型为链表,链表的数据类型为int,链表长度为20
- LinearList<LinkList, int, 20> a;
- a.insert();
- a.ddelete();
- a.update();
- LinearList<Array, string, 20> b;
- b.insert();
- b.ddelete();
- b.update();
- return 0;
- }
复制代码 运行效果如下:
LinkList 插入操作
LinkList 删除操作
LinkList 更新操作
Array 插入操作
Array 删除操作
Array 更新操作
感谢欣赏,一起学习!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |