C++程序笔记——模板

    科技2022-07-11  89

    文章目录

    函数模板概述函数模板的底层原理实例分析总结 类模板概述定义 C++程序运行实例注意关于模板类的静态成员 模板实例函数模板实例概述C++程序实例 分析与总结 类模板程序实例分析与总结

    函数模板

    概述

    当有多个函数,他们除了形参列表的数据类型和返回类型不同之外,在函数体中所执行的操作完全相同,可以使用函数模板来对其进行统一的代替。通过模板函数,减少重复的代码的出现,方便编程

    函数模板的底层原理

    首先程序在编译时候,在没有调用函数模板代指的函数的时候,并不会的会模板函数产生相关的执行代码。当程序调用函数模板指代的函数的时候,会将特定的数据类型换入到函数模板中进行替换,将函数模板转成对应的模板函数,并生成相关的执行代码。不调用,无执行代码;调用,生成特定数据类型的执行代码。

    实例

    编写程序,功能是查找一维数组a中的第一个值为x的元素的下标。如果不存在该元素就返回-1

    functionTemplate.h文件

    #ifndef _FUNCTIONTEMPLATE_H #define _FUNCTIONTEMPLATE_H #include <iostream> using namespace std; template <typename T> T maxElement(T a,T b) { return a>b?a:b; } /* description:search the element x in the array a. return the index where it firstly appear. */ template <typename T> int findElement(T a[],T x,int n) { for(int i = 0;i < n;i ++) { if(a[i] == x) return i; } return -1; } /* description:show different type of array */ template <typename T> void show(T a[],int n) { for(int i =0;i < n;i ++) { cout<<a[i]<<" "; } cout<<endl; } #endif // _FUNCTIONTEMPLATE_H main测试文件 #include <iostream> #include "functionTemplate.h" using namespace std; int main() { int a[6]; double b[6]; char c[6]; for(int i = 0;i < 6; i++) { a[i] = i; b[i] = i; c[i] = 'a' + i; } show(a,6); cout<<endl; show(b,6); cout<<endl; show(c,6); cout<<endl; cout<<findElement(a,3,6)<<endl; cout<<findElement(b,(double)3,6)<<endl; cout<<findElement(c,'d',6)<<endl; return 0; }

    分析总结

    函数模板是方便编程,减少了重复代码的书写,对于底层的程序运作,程序的执行代码仍旧是那么长函数模板经过程序调用,传入了特定类型的参数,实例化成对应的模板函数

    类模板

    概述

    对于仅仅只有特定的数据类型不同的类,可以使用模板类去替代所有的类。比如,C++中的vector就有各种数据类型的vector,整型的,浮点型的等等,但是其功能和函数都是一致的,所以没有必要根据不同数据类型,写大量近似的数据类型。使用模板类来代替
    定义

    类定义 类体外的成员函数的定义

    使用

    C++程序运行实例

    编写一个模板类Array 成员:为模板类型的一维数组成员函数: 获取自身的长度getLength()获取特定索引的元素getElement()修改所有的元素为一个统一的值setElement()

    Array.h文件

    #ifndef _ARRAY_H #define _ARRAY_H using namespace std; template <typename T,int length> class Array { private: T buffer[length]; public: T getElement(int i) { return buffer[i]; } int getLength() { return sizeof(buffer)/sizeof(T); } void setElement(T x); }; template <typename T,int length> void Array<T,length>::setElement(T x) { for(int i = 0 ;i < getLength();i ++) { buffer[i] = x; } } #endif // _ARRAY_H

    main函数测试文件

    #include <iostream> #include "Array.h" using namespace std; int main() { Array<int,10> a; Array<double,20> b; Array<char,30> c; cout<<"the length of object a is:"<<a.getLength()<<endl; cout<<"the length of object b is:"<<b.getLength()<<endl; cout<<"the length of object c is:"<<c.getLength()<<endl; a.setElement(100); b.setElement(12.5); c.setElement('\n'); cout<<"the third element fo the array a is :"<<a.getElement(3)<<endl; cout<<"the third element fo the array b is :"<<b.getElement(3)<<endl; cout<<"the third element fo the array c is :"<<c.getElement(3)<<endl; return 0; }

    注意
    需要将类的模板声明和类模板成员函数的定义放在同一个头文件
    关于模板类的静态成员
    在模板类中定义了静态成员,也不会为其分配内存空间,需要在类体外进行的声明和定义需要将模板类实例化之后,才能够创建对应的类的静态对象,所有的实例化成员共享要给类的静态成员

    模板实例

    函数模板实例

    概述

    设计两个的函数模板,其功能分别是返回两个值中的较大者和返回多个值中的较大者。要求不仅能够处理整型、实型等数值性数据,而且能够省却处理字符串

    C++程序实例
    描述:设计两个函数模板,其功能分别是返回两个值中的较大者和 返回多个值中的较大者。要求不仅能够处理整型、实型等数值型数据,而且能够正确处理字符串。functemplate.h文件 #ifndef _FUNCTIONTEMPLATE_H #define _FUNCTIONTEMPLATE_H #include <iostream> using namespace std; template <typename T> T maxElement(T a,T b) { return a>b?a:b; } template <typename T> T maxElement(T a[],int size) { cout<<"template <typename T>T maxElement is being used!"<<endl; T max = a[0]; for(int i = 1;i < size; i++) { max = maxElement(max,a[i]); } return max; } #endif functiontemplate.cpp文件 #include "functionTemplate.h" #include <string.h> using namespace std; char *maxElement(char *a,char *b) { cout<<"char *maxElement(char *a,char *b) is being used"<<endl; if(strcmp(a,b)) { return a; } return b; } main函数测试文件 #include <string.h> #include <iostream> #include "functionTemplate.h" using namespace std; int main() { int nArr[] = {3,5,7,16,9,2}; double dArr[] = {3.5,7.2,4.3,6.8}; char cArr[] = {'a','b','c','d'}; char *sArr[] = {"Guolong","chening","wuhaolong"}; cout<<maxElement(3,5)<<endl; cout<<maxElement(3.5,5.2)<<endl; cout<<maxElement('a','b')<<endl; cout<<maxElement(sArr[0],sArr[1])<<endl; cout<<maxElement(nArr,6)<<endl; cout<<maxElement(dArr,4)<<endl; cout<<maxElement(cArr,4)<<endl; cout<<maxElement(sArr,3)<<endl; return 0; } 运行结果

    分析与总结
    在上述的问题中不能,模板函数并不能实现字符串的比较,所以只能通过对函数的重定义进行来实现,在cpp文件中实现函数使用模板函数确实能够的极大的减少代码的复用率,提高编码效率

    类模板程序实例

    描述:数组Array的实现

    成员:数组的指针 和 数组的实际长度成员函数:带参数的构造函数(参数为对应的长度)、析构函数、下标符号的重载(返回特定索引的元素引用)、输出当前的元素和增加数组的长度

    Arraytemplate.h文件

    #ifndef _ARRAYTEMPLATE_ #include <iostream> using namespace std; template <class T> class Array { private: T *m_pArray; int m_nSize; public: Array(int nSize); ~Array(); T& operator[](int index); int Size(){return m_nSize;} bool addNewElement(int nAddSize); void display(); }; //construct the array without any initialization template<class T> Array<T>::Array(int nSize) { m_nSize = nSize; m_pArray = new T[nSize + 1]; } //destructor of the class template <class T> Array<T>::~Array() { delete []m_pArray; } //the overload of the operator[] template <class T> T& Array<T>::operator[](int index) { if(index >= m_nSize || index < 0) { cout<<"error:out of edge!"<<endl; //use the superfluous space to store the illegal value; index = m_nSize; m_pArray[index] = 0; } return m_pArray[index]; } //show the array template <class T> void Array<T>::display() { for(int i = 0;i < m_nSize;i ++) { cout<<m_pArray[i]<<" "; } cout<<endl; } //mix the two array together template <class T> bool Array<T>::addNewElement(int nAddSize) { if(nAddSize <= 0) { cout<<"the new array you add must over zero!"<<endl; return false; } T *pNewArray = new T[m_nSize + nAddSize]; if(pNewArray == NULL) { cout<<"Error:arrange the memory absortively"<<endl; return false; } for(int i = 0 ;i < m_nSize;i ++) { pNewArray[i] = m_pArray[i]; } delete []m_pArray; m_pArray = pNewArray; m_nSize = m_nSize + nAddSize; return true; } #endif // _ARRAYTEMPLATE_ main测试文件 #include <iostream> #include "Arraytemplate.h" using namespace std; int main() { Array<int> intArray(10); Array<double> doubleArray(10); Array<char> charArray(10); for(int i = 0;i < 10; i++) { intArray[i] = 1 + i; doubleArray[i] = 2.5 + i; charArray[i] = 'a' + i; } intArray.display(); doubleArray.display(); charArray.display(); intArray[10] = 20; intArray.display(); intArray.addNewElement(1); intArray[10] = 20; intArray.display(); return 0; 测试结果

    分析与总结
    在模板形参列表中使用typename和class是一样的效果 主要是形式化的定义,记住这些格式即可
    Processed: 0.027, SQL: 8