软件需求请点击此处留言菜鸟资源为你准备 立即查看

第十六章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

第十六章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

模板(Templates)在编程中是一个非常重要的概念,特别是在C++中。它是一种泛型编程的技术,允许程序员定义处理未知数据类型的函数或类。通过使用模板,程序员可以编写处理任意数据类型的代码,而不需要对每种数据类型都重写代码。 模板可以分为...

当前版本

软件大小

软件语言

是否破解

模板(Templates)在编程中是一个非常重要的概念,特别是在C++中。它是一种泛型编程的技术,允许程序员定义处理未知数据类型的函数或类。通过使用模板,程序员可以编写处理任意数据类型的代码,而不需要对每种数据类型都重写代码。

模板可以分为函数模板和类模板两种类型。函数模板允许程序员定义一个可以处理不同数据类型的函数,而类模板则允许程序员定义一个可以处理不同数据类型的类。

函数模板的一般形式如下:

  1. template <typename T>
  2. void functionName(T param) {
  3. // 函数体
  4. }

在这个例子中,T 是一个类型参数,表示函数可以接受任何类型的参数。在函数体中,T 可以被用作任何类型,包括变量声明、返回类型等。

类模板的一般形式如下:

  1. template <typename T>
  2. class ClassName {
  3. // 类体
  4. };

在这个例子中,T 是一个类型参数,表示类可以包含任何类型的成员变量或函数。在类体中,T 可以被用作任何类型,包括变量声明、返回类型等。

通过使用模板,程序员可以编写更加通用和可复用的代码,提高代码的利用率和可维护性。同时,模板还可以提高代码的安全性,因为类型检查在编译时进行,而不是在运行时进行。

第十六章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

接上一章继续:第十五章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人 – 菜鸟资源 (xiciw.com)

9. 模板(Templates)

泛型(Generic Programming)即是指具有在多种数据类型上皆可操作的含意。泛型编程的代表作品 STL 是一种高效、泛型、可交互操作的软件组件。

泛型编程最初诞生于 C++中,目的是为了实现 C++的 STL(标准模板库)。其语言支持机制就是模板(Templates)。模板的精神其实很简单:参数化类型。换句话说,把一个原本特定于某个类型的算法或类当中的类型信息抽掉,抽出来做成模板参数 T。

9.1. 函数模板

9.1.1. 函数重载实现的泛型

  1. #include <iostream>
  2. using namespace std;
  3. void swap(int &a, int& b)
  4. {
  5. int t = a;
  6. a = b;
  7. b = t;
  8. }
  9. void swap(double &a,double b)
  10. {
  11. double t = a;
  12. a = b;
  13. b = t;
  14. }
  15. int main()
  16. {
  17. int ia = 10; int ib = 20;
  18. swap(ia,ib);
  19. cout<<ia<<ib<<endl;
  20. double da = 10, db = 20;
  21. swap(da,db);
  22. cout<<da<<db<<endl;
  23. return 0;
  24. }

9.1.2. 函数模板的引入

 语法格式

  1. template<typename/class 类型参数表>
  2. 返回类型 函数模板名(函数参数列表)
  3. {
  4. 函数模板定义体
  5. }

template 是语义是模板的意思,尖括号中先写关键字 typename 或是 class ,后面跟一个类型 T,此类即是虚拟的类型。至于为什么用 T,用的人多了,也就是 T 了。

9.1.3. 函数模板的实例

调用过程是这样的,先将函数模板实再化为函数,然后再发生函数调用。

  1. #include <iostream>
  2. using namespace std;
  3. template <typename T>
  4. void Swap(T& a,T &b )
  5. {
  6. T t = a;
  7. a = b;
  8. b = t;
  9. }
  10. int main()
  11. {
  12. int ia = 10; int ib = 20;
  13. Swap(ia,ib); //Swap<int>(ia,ib);
  14. cout<<ia<<ib<<endl;
  15. double da = 10, db = 20;
  16. Swap(da,db); //Swap<double>(da,db);
  17. cout<<da<<db<<endl;
  18. string sa ="china"; string sb = "America";
  19. Swap(sa,sb);
  20. cout<<sa<<sb<<endl;
  21. return 0;
  22. }

9.1.4. 小结
函数模板,只适用于函数的参数个数相同而类型不同,且函数体相同的情况。如果个数不同,则不能用函数模板。
9.2. 类模板
9.2.1. 引例
Stack 类

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. using namespace std;
  6. class Stack
  7. {
  8. public:
  9. Stack(int size=1024);
  10. ~Stack();
  11. bool isEmpty();
  12. bool isFull();
  13. void push(int data);
  14. int pop();
  15. private:
  16. int* space;
  17. int top;
  18. };
  19. Stack::Stack(int size)
  20. {
  21. space = new int[size];
  22. top = 0;
  23. }
  24. Stack::~Stack()
  25. {
  26. delete []space;
  27. }
  28. bool Stack::isEmpty()
  29. {
  30. return top == 0;
  31. }
  32. bool Stack::isFull()
  33. {
  34. return top == 1024;
  35. }
  36. void Stack::push(int data)
  37. {
  38. space[top++] = data;
  39. }
  40. int Stack::pop()
  41. {
  42. return space[--top];
  43. }
  44. int main()
  45. {
  46. Stack s(100);
  47. if(!s.isFull())
  48. s.push(10);
  49. if(!s.isFull())
  50. s.push(20);
  51. if(!s.isFull())
  52. s.push(30);
  53. if(!s.isFull())
  54. s.push(40);
  55. if(!s.isFull())
  56. s.push(50);
  57. while(!s.isEmpty())
  58. cout<<s.pop()<<endl;
  59. return 0;
  60. }

上述栈,如果想模板化,可以 push 和 pop 不同的数据类型。主要由几个因素需要把控。栈中的空间元素类型,压入元素类型,弹出元素类型,三者保持一致即可。

9.2.2. 类模板语法

9.2.2.1. 类模板定义

  1. template<typename T>
  2. class Stack
  3. {
  4. }

9.2.2.2. 类内定义成员函数

  1. template<typename T>
  2. class Stack
  3. {
  4. public:
  5. Stack(int size)
  6. {
  7. space = new T[size];
  8. top = 0;
  9. }
  10. }

9.2.2.3. 类外定义函数

  1. template<typename T>
  2. void Stack<T>::push(T data)
  3. {
  4. space[top++] = data;
  5. }

9.2.2.4. 类模板实例化为模板类

类模板是类的抽象,类是类模板的实例。

  1. Stack<double> s(100);

9.2.3. 类模板实例

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. 145
  5. #include <string.h>
  6. using namespace std;
  7. template<typename T>
  8. class Stack
  9. {
  10. public:
  11. Stack(int size)
  12. {
  13. space = new T[size];
  14. top = 0;
  15. }
  16. ~Stack();
  17. bool isEmpty();
  18. bool isFull();
  19. void push(T data);
  20. T pop();
  21. private:
  22. T* space;
  23. int top;
  24. };
  25. template<typename T>
  26. Stack<T>::~Stack()
  27. {
  28. delete []space;
  29. }
  30. template<typename T>
  31. bool Stack<T>::isEmpty()
  32. {
  33. return top == 0;
  34. }
  35. template<typename T>
  36. bool Stack<T>::isFull()
  37. {
  38. return top == 1024;
  39. }
  40. template<typename T>
  41. void Stack<T>::push(T data)
  42. {
  43. space[top++] = data;
  44. }
  45. template<typename T>
  46. T Stack<T>::pop()
  47. {
  48. return space[--top];
  49. }
  50. int main()
  51. {
  52. Stack<double> s(100); //Stack<string> s(100);
  53. if(!s.isFull())
  54. s.push(10.3);
  55. if(!s.isFull())
  56. s.push(20);
  57. if(!s.isFull())
  58. s.push(30);
  59. if(!s.isFull())
  60. s.push(40);
  61. if(!s.isFull())
  62. s.push(50);
  63. while(!s.isEmpty())
  64. cout<<s.pop()<<endl;
  65. return 0;
  66. }

9.2.4. 练习

模拟 STL 中 vector 的用法,自己实现之。

  1. #ifndef MYVECTOR_HPP
  2. #define MYVECTOR_HPP
  3. #include <iostream>
  4. using namespace std;
  5. template <typename T> class MyVector;
  6. template <typename T> ostream & operator<<(ostream &out, const MyVector<T> &obj);
  7. template <typename T>
  8. class MyVector
  9. {
  10. public:
  11. MyVector(int size = 0);
  12. MyVector(const MyVector<T> &obj);
  13. MyVector<T> & operator=( MyVector<T> &obj);
  14. ~MyVector();
  15. T& operator[] (int index);
  16. int getSize();
  17. friend ostream & operator<< <T>(ostream &out, const MyVector<T> &obj);
  18. protected:
  19. T *m_space;
  20. int m_len;
  21. };
  22. template <typename T>
  23. int MyVector<T>::getSize()
  24. {
  25. return m_len;
  26. }
  27. template <typename T>
  28. ostream & operator<< (ostream &out, const MyVector<T> &obj)
  29. {
  30. for (int i=0; i< obj.m_len; i++)
  31. {
  32. out << obj.m_space[i] << " ";
  33. }
  34. out << endl;
  35. return out;
  36. }
  37. template <typename T>
  38. MyVector<T>::MyVector(int size)
  39. {
  40. m_space = new T[size];
  41. m_len = size;
  42. }
  43. template <typename T>
  44. MyVector<T>::MyVector(const MyVector & obj)
  45. {
  46. m_len = obj.m_len;
  47. m_space = new T[m_len];
  48. for (int i=0; i<m_len; i++)
  49. {
  50. m_space[i] = obj.m_space[i];
  51. }
  52. }
  53. template <typename T>
  54. MyVector<T>::~MyVector() //析构函数
  55. {
  56. if (m_space != NULL)
  57. {
  58. delete [] m_space;
  59. m_space = NULL;
  60. m_len = 0;
  61. }
  62. }
  63. template <typename T>
  64. T& MyVector<T>::operator[] (int index)
  65. {
  66. return m_space[index];
  67. }
  68. template <typename T>
  69. MyVector<T> & MyVector<T>::operator=( MyVector<T> &obj)
  70. {
  71. delete[] m_space;
  72. m_space = NULL;
  73. m_len = 0;
  74. m_len = obj.m_len;
  75. m_space = new T[m_len];
  76. for (int i=0; i<m_len; i++)
  77. {
  78. m_space[i] = obj[i];
  79. }
  80. return *this;
  81. }
  82. #endif // MYVECTOR_HPP

测试代码:

  1. #include <iostream>
  2. #include "myvector.hpp"
  3. using namespace std;
  4. int main()
  5. {
  6. MyVector<int> a(10);
  7. for(int i=0; i<10; i++)
  8. {
  9. a[i] = i+100;
  10. }
  11. MyVector<int> b(a);
  12. cout<<b[2]<<b[1]<<endl;
  13. MyVector<int> c;
  14. c = a;
  15. cout<<b[2]<<b[1]<<endl;
  16. cout<<a;
  17. return 0;
  18. }

注:

《C++编程思想》第 15 章(第 300 页):

模板定义很特殊。由 template<…> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

常见问题

  • 如何安装和激活?

    每款软件会附带有安装教程,您打开安装包一目了然

  • 程序是否已损坏?文件损坏?还是其他错误?

    有错误问题,请您参考:https://www.xxx.com/error

  • 如何更新?正式激活后会发生什么情况?

    除非安装说明中另有说明,否则官方更新可能会导致无法激活。 要从本网站更新软件,您需要在此处下载此软件的新版本(如果可用),并将其安装在计算机上安装的版本之上(替换)。在这种情况下,您将保存此软件的激活和设置。

  • 如何下载?链接不起作用?

    我们使用百度网盘,132云盘和微软网盘,除了百度网盘,其他两款不限速,如果链接失效,请您联系客服处理

  • 已发布更新。我什么时候升级我的版本?

    所有软件如有更新,我们第一时间推送,视自己情况更新使用

  • 如何更改语言?

    打开“系统偏好设置”->“通用>语言和地区”->应用程序-“+”。 选择应用和语言。此方法适用于大多数应用程序。 Adobe 产品中的语言通常是在产品本身的安装阶段选择的。 游戏中的语言通常会在游戏本身的设置中发生变化。

  • 如何删除软件?

    有很多选择。最简单的方法是使用特殊的实用程序来卸载应用程序,例如App Cleaner Uninstaller 要删除 Adobe 产品,请使用 Creative Cloud Cleaner Tool

  • 需要远程帮助吗?

    网站已开通永久会员的可享受免费远程,如果非永久会员,远程安装另外收费

技术教程

第十五章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

2024-2-4 9:30:00

技术教程

第十七章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人

2024-2-6 9:30:00

0 条回复 A文章作者 M管理员
有些面具戴得太久,就摘不下来了
欢迎您,新朋友,感谢参与互动!
    暂无讨论,说说你的看法吧
后退
榜单