C++ —— 模板类扩展

打印 上一主题 下一主题

主题 1524|帖子 1524|积分 4572

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
模板类的成员模板

结构体中可以有结构体,类中可以有类和成员函数。那么,模板类中也应该可以有模板类和模板函数。
在类AA中再创建一个模板类和模板函数。
先创建模板类,代码如下:
  1. #include <iostream>
  2. using namespace std;
  3. template <class T1, class T2>
  4. class AA {
  5. public:   
  6.     T1 m_x;
  7.     T2 m_y;
  8.     AA(const T1 x, const T2 y): m_x(x), m_y(y) {}
  9.     void show() {cout << "AA的show ~ m_x = " << m_x << ", m_y = " << m_y << endl;}
  10.     template <class T>
  11.     class BB{
  12.     public:
  13.         T m_b;
  14.         // 可以用AA的模板参数T1、T2创建成员变量
  15.         T1 m_bx;
  16.         BB() {}
  17.         void show() {cout << "BB的show ~ m_b = " << m_b << ", m_bx = " << m_bx << endl;}
  18.     };
  19.     BB<string> bb; // 对象bb就是类模板AA的成员
  20.     template <typename T> // 再创建一个函数模板,这个T和BB中的T没有关系
  21.     void show(T t) {
  22.         cout << "模板函数show ~ t = " << t << endl;
  23.         cout << "AA ~ m_x = " << m_x << ", m_y = " << m_y << endl;
  24.         bb.show();
  25.     }
  26. };
  27. int main() {
  28.     AA<int, string> aa(123, "你好");
  29.     aa.show();
  30.     aa.bb.m_b = "哈哈";
  31.     aa.bb.m_bx = 666;
  32.     aa.bb.show();
  33.     aa.show<string> ("嘻嘻嘻");
  34.     return 0;
  35. }
复制代码
运行效果如下:
   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
  模板类中的成员模板,定义可以写在类的外面。修改后的代码如下:
  1. #include <iostream>
  2. using namespace std;
  3. template <class T1, class T2>
  4. class AA {
  5. public:   
  6.     T1 m_x;
  7.     T2 m_y;
  8.     AA(const T1 x, const T2 y): m_x(x), m_y(y) {}
  9.     void show() {cout << "AA的show ~ m_x = " << m_x << ", m_y = " << m_y << endl;}
  10.     template <class T>
  11.     class BB{
  12.     public:
  13.         T m_b;
  14.         // 可以用AA的模板参数T1、T2创建成员变量
  15.         T1 m_bx;
  16.         BB() {}
  17.         void show();
  18.     };
  19.     BB<string> bb; // 对象bb就是类模板AA的成员
  20.     template <typename T> // 再创建一个函数模板,这个T和BB中的T没有关系
  21.     void show(T t);
  22. };
  23. // 模板类中的成员模板,定义可以写在类的外面。
  24. template <class T1, class T2>
  25. template <class T>
  26. void AA<T1, T2>::BB<T>::show() {
  27.     {cout << "BB的show ~ m_b = " << m_b << ", m_bx = " << m_bx << endl;}
  28. }
  29. template <class T1, class T2>
  30. template <typename T>
  31. void AA<T1, T2>::show(T t) {
  32.     cout << "模板函数show ~ t = " << t << endl;
  33.     cout << "AA ~ m_x = " << m_x << ", m_y = " << m_y << endl;
  34.     bb.show();
  35. }
  36. int main() {
  37.     AA<int, string> aa(123, "你好");
  38.     aa.show();
  39.     aa.bb.m_b = "哈哈";
  40.     aa.bb.m_bx = 666;
  41.     aa.bb.show();
  42.     aa.show<string> ("嘻嘻嘻");
  43.     return 0;
  44. }
复制代码
运行效果跟之前保持同等:
   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++的类模板主要是为了解决数据结构的问题。线性表有:链表、数组、栈、和队列。以链表和数组为例,为了支持任意类型数据,最好的方法就是用类模板来实现,代码如下:
  1. #include <iostream>
  2. using namespace std;
  3. template <class T, int len> // 实际上,链表没有长度的说法,但为了演示,假定有一个长度
  4. class LinkList {
  5. public:
  6.     T* m_head; // 定义链表头节点指针
  7.     int m_len = len; // 指定表长度
  8.     // 链表常用操作
  9.     void insert() {cout << "LinkList 插入操作" << endl;}
  10.     void ddelete() {cout << "LinkList 删除操作" << endl;}
  11.     void update() {cout << "LinkList 更新操作" << endl;}
  12. };
  13. template <class T, int len>
  14. class Array{
  15. public:
  16.     T* m_data;
  17.     int m_len = len;
  18.     void insert() {cout << "Array 插入操作" << endl;}
  19.     void ddelete() {cout << "Array 删除操作" << endl;}
  20.     void update() {cout << "Array 更新操作" << endl;}
  21. };
  22. int main() {
  23.         return 0;
  24. }
复制代码
模板的目的就是代码重用,既然链表和数组的逻辑结构是一样的,那就把它们改成模板类的形式。现在模板LinkList和Array,是为了兼容各种各样的数据类型,解决的是物理结构问题。接下来把它们再次模板化,是从逻辑角度来思量的。C++支持模板的模板,意思是把模板名当成一种特别的数据类型。实例化对象的时候,可以用模板签名作为参数,传给模板。示例代码如下:
  1. #include <iostream>
  2. using namespace std;
  3. template <class T, int len> // 实际上,链表没有长度的说法,但为了演示,假定有一个长度
  4. class LinkList {
  5. public:
  6.     T* m_head; // 定义链表头节点指针
  7.     int m_len = len; // 指定表长度
  8.     // 链表常用操作
  9.     void insert() {cout << "LinkList 插入操作" << endl;}
  10.     void ddelete() {cout << "LinkList 删除操作" << endl;}
  11.     void update() {cout << "LinkList 更新操作" << endl;}
  12. };
  13. template <class T, int len>
  14. class Array{
  15. public:
  16.     T* m_data;
  17.     int m_len = len;
  18.     void insert() {cout << "Array 插入操作" << endl;}
  19.     void ddelete() {cout << "Array 删除操作" << endl;}
  20.     void update() {cout << "Array 更新操作" << endl;}
  21. };
  22. // 线性表模板类:其中,tabletype 表示 线性表类型,datatype 表示 线性表数据类型,len 表示 长度
  23. // tabletype 不是一个普通的参数,而是模板,意思是这个参数要填模板名。
  24. // 填什么样的模板名呢?填有两个参数的类模板名。并且,要求类模板的第一个参数是通用类型,第二个是非通用类型。
  25. // 此外,class可以用typename代替,只是class更直观。
  26. // tabletype只是一个模板名,用T1创建对象时,还需要指定具体的数据类型。
  27. // 常见的做法是:具体的数据类型用模板参数从外面传进来
  28. template<template<class, int>class tabletype, class datatype, int len> // 模板参数列表
  29. class LinearList{
  30. public:
  31.     tabletype<datatype, len> m_table; // 创建线性表对象
  32.     void insert() {m_table.insert();}
  33.     void ddelete() {m_table.ddelete();}
  34.     void update() {m_table.update();}
  35. };
  36. int main() {
  37.     // 创建线性表对象,容器类型为链表,链表的数据类型为int,链表长度为20
  38.     LinearList<LinkList, int, 20> a;
  39.     a.insert();
  40.     a.ddelete();
  41.     a.update();
  42.     LinearList<Array, string, 20> b;
  43.     b.insert();
  44.     b.ddelete();
  45.     b.update();
  46.     return 0;
  47. }
复制代码
运行效果如下:
   LinkList 插入操作
LinkList 删除操作
LinkList 更新操作
Array 插入操作
Array 删除操作
Array 更新操作
  感谢欣赏,一起学习!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张国伟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表