1. 简述
泛型编程是一种编程风格,可以开发一套代码适应不同的数据类型。
C++中,泛型编程是通过模板来实现的。模板是C++支持参数化多态的工具,使用模板可以使用户为类属类型(如数组的元素类型和容器的数据类型)编写通用的代码,然后再编写特定的类型来创建类属类型的特定实例。
模板是一种对类型进行参数化的工具,通常有两种形式:模板函数和模板类。
2. 模板函数
模板函数允许以类型作为参数来定义函数,从而实现对不同类型数据的相同操作。下面是一个简单的模板函数例子,该函数接受两个同类型参数,并返回它们的和。
模板函数的定义:
template <typename T> T add(T a, T b){return a + b; }
在这个例子中,template <typename T>是模板声明,它告诉编译器我们将要使用一个类型参数T。在函数体中,我们可以用T作为类型来声明变量,或者用它来调用T类型的成员函数。这样,我们就可以用这个模板函数来操作多种数据类型。
模板函数的使用:
int main(int argc, char* argv[]){int a = 1, b = 2; float c = 1.1, d = 2.2; std::cout << add<int>(a, b) << std::endl; ///< 输出3 std::cout << add<float>(c, d) << std::endl; ///< 输出3.3 return 0; }
3. 模板类
当我们需要编写一个类,可以支持多种不同的数据类型时,我们可定义一个模板类。
模板类的定义举例如下,在如下代码中,我们定义了一个动态数组类,这个类可以支持多种不同的类型构成数组,并操作他们。
template <class T> class DynamicArray{private: T* array; int size; public: DynamicArray(T arr[], int s); void print(); ~DynamicArray(); }; template <class T> DynamicArray<T>::DynamicArray(T arr[], int s){size = s; array = new T[s]; for (int i = 0; i < size; i++) { array[i] = arr[i]; } } template <class T> void DynamicArray<T>::print(){for (int i = 0; i < size; i++) { std::cout << array[i] << " "; } std::cout << std::endl; } template <class T> DynamicArray<T>::~DynamicArray(){delete[] array; }
在上述例子中,我们定义了一个名为DynamicArray的模板类,该类有一个私有成员变量array(一个动态分配的数组)和一个公有成员变量size(表示数组的大小)。这个类有一个构造函数,用于初始化数组和大小,有一个print函数用于打印数组,和一个析构函数用于释放内存。这样我们就可以用这个模板类来创建不同类型的动态数组,例如:
int main(int argc, char* argv[]){int arr[5] = {1, 2, 3, 4, 5}; DynamicArray<int> intArray(arr, 5); intArray.print(); ///< 输出1 2 3 4 5 double darr[3] = {1.1, 2.2, 3.3}; DynamicArray<double> doubleArray(darr, 3); doubleArray.print(); ///< 输出1.1 2.2 3.3 return 0; }