跳到主要内容

C++类模板

提示
  1. 类模板声明:类模板使用关键字template,后跟模板参数,允许创建单个类以处理不同数据类型。类模板可使代码更简短和可管理。
  2. 创建类模板对象:定义类模板后,可在其他类或函数中创建其对象,使用语法className<dataType> classObject;,例如className<int> classObject;
  3. 类模板成员函数定义:若需在类模板外定义函数,则需要重复使用template <class T>语法,并按照格式returnType ClassName<T>::functionName()定义函数。

模板是 C++ 强大的特性之一,它允许我们编写通用程序。我们可以通过两种方式实现模板:

  • 函数模板
  • 类模板

类似于函数模板,我们可以使用类模板来创建一个单一的类来处理不同的数据类型。

类模板在使我们的代码更短、更易管理方面非常有用。

类模板声明

类模板以关键字 template 开头,后跟 <> 中的模板参数,然后是类声明。

template <class T>
class className {
private:
T var;
... .. ...
public:
T functionName(T arg);
... .. ...
};

在上述声明中,T 是模板参数,是用于数据类型的占位符,而 class 是一个关键字。

在类主体内,成员变量 var 和成员函数 functionName() 都是类型 T

创建类模板对象

一旦我们声明并定义了一个类模板,我们就可以在其他类或函数(如 main() 函数)中使用以下语法创建其对象

className<dataType> classObject;

例如,

className<int> classObject;
className<float> classObject;
className<string> classObject;

示例 1:C++ 类模板

// C++ 程序演示类模板的使用

#include <iostream>
using namespace std;

// 类模板
template <class T>
class Number {
private:
// 类型为 T 的变量
T num;

public:
Number(T n) : num(n) {} // 构造函数

T getNum() {
return num;
}
};

int main() {

// 创建 int 类型的对象
Number<int> numberInt(7);

// 创建 double 类型的对象
Number<double> numberDouble(7.7);

cout << "int 数字 = " << numberInt.getNum() << endl;
cout << "double 数字 = " << numberDouble.getNum() << endl;

return 0;
}

输出

int 数字 = 7
double 数字 = 7.7

在这个程序中,我们创建了一个名为 Number 的类模板

template <class T>
class Number {
private:
T num;

public:
Number(T n) : num(n) {}
T getNum() { return num; }
};

注意变量 num、构造函数参数 n 和函数 getNum() 都是类型 T,或者有返回类型 T。这意味着它们可以是任何类型。

main() 中,我们通过创建其对象来实现了类模板

Number<int> numberInt(7);
Number<double> numberDouble(7.7);

注意上面代码中的 Number<int>Number<double>

这为 intfloat 创建了各自的类定义,然后相应地使用。

在声明类模板的对象时指定类型是一个好习惯。否则,一些编译器可能会报错。

//错误
Number numberInt(7);
Number numberDouble(7.7);

在类模板外定义类成员

假设我们需要在类模板外定义一个函数。我们可以使用以下代码来实现:

template <class T>
class ClassName {
... .. ...
// 函数原型
returnType functionName();
};

// 函数定义
template <class T>
returnType ClassName<T>::functionName() {
// 代码
}

注意在类外定义函数时,代码 template <class T> 被重复了。这是必需的,也是语法的一部分。

如果我们查看 示例 1 中的代码,我们有一个在类模板 Number 内定义的函数 getNum()

我们可以使用以下代码在 Number 外定义 getNum()

template <class T>
class Number {
... .. ...
// 函数原型
T getnum();
};

// 函数定义
template <class T>
T Number<T>::getNum() {
return num;
}

示例 2:使用类模板的简单计算器

该程序使用类模板执行两个变量 num1 和 num2 的加法、减法、乘法和除法。

变量可以是任何类型,尽管在这个示例中我们只使用了 intfloat 类型。

#include <iostream>
using namespace std;

template <class T>
class Calculator {
private:
T num1, num2;

public:
Calculator(T n1, T n2) {
num1 = n1;
num2 = n2;
}

void displayResult() {
cout << "数字: " << num1 << " 和 " << num2 << "." << endl;
cout << num1 << " + " << num2 << " = " << add() << endl;
cout << num1 << " - " << num2 << " = " << subtract() << endl;
cout << num1 << " * " << num2 << " = " << multiply() << endl;
cout << num1 << " / " << num2 << " = " << divide() << endl;
}

T add() { return num1 + num2; }
T subtract() { return num1 - num2; }
T multiply() { return num1 * num2; }
T divide() { return num1 / num2; }
};

int main() {
Calculator<int> intCalc(2, 1);
Calculator<float> floatCalc(2.4, 1.2);

cout << "Int 结果:" << endl;
intCalc.displayResult();

cout << endl
<< "Float 结果:" << endl;
floatCalc.displayResult();

return 0;
}

输出

Int 结果:
数字: 21.
2 + 1 = 3
2 - 1 = 1
2 * 1 = 2
2 / 1 = 2

Float 结果:
数字: 2.41.2.
2.4 + 1.2 = 3.6
2.4 - 1.2 = 1.2
2.4 * 1.2 = 2.88
2.4 / 1.2 = 2

在上述程序中,我们声明了一个名为 Calculator 的类模板。

该类包含两个类型为 T 的私有成员:num1 和 num2,以及一个初始化这些成员的构造函数。

我们还有 add()subtract()multiply()divide() 函数,它们的返回类型为 T。我们还有一个 void 函数 displayResult(),它打印出其他函数的结果。

main() 中,我们为 Calculator 创建了两个对象:一个用于 int 数据类型,另一个用于 float 数据类型。

Calculator<int> intCalc(2, 1);
Calculator<float> floatCalc(2.4, 1.2);

这会促使编译器在编译期间为相应的数据类型创建两个类定义。

C++ 类模板带多个参数

在 C++ 中,我们可以使用多个模板参数,甚至为这些参数使用默认参数。例如,

template <class T, class U, class V = int>
class ClassName {
private:
T member1;
U member2;
V member3;
... .. ...
public:
... .. ...
};

示例 3:C++模板带有多个参数

#include <iostream>
using namespace std;

// 类模板具有多个和默认参数
template <class T, class U, class V = char>
class ClassTemplate {
private:
T var1;
U var2;
V var3;

public:
ClassTemplate(T v1, U v2, V v3) : var1(v1), var2(v2), var3(v3) {} // 构造函数

void printVar() {
cout << "var1 = " << var1 << endl;
cout << "var2 = " << var2 << endl;
cout << "var3 = " << var3 << endl;
}
};

int main() {
// 创建具有int、double和char类型的对象
ClassTemplate<int, double> obj1(7, 7.7, 'c');
cout << "obj1的值: " << endl;
obj1.printVar();

// 创建具有double、char和bool类型的对象
ClassTemplate<double, char, bool> obj2(8.8, 'a', false);
cout << "\nobj2的值: " << endl;
obj2.printVar();

return 0;
}

输出

obj1的值:
var1 = 7
var2 = 7.7
var3 = c

obj2的值:
var1 = 8.8
var2 = a
var3 = 0

在这个程序中,我们创建了一个名为ClassTemplate的类模板,有三个参数,其中一个是默认参数。

template <class T, class U, class V = char>
class ClassTemplate {
// 代码
};

注意代码class V = char。这意味着V是一个默认参数,其默认类型为char

ClassTemplate内部,我们声明了3个变量var1、var2和var3,每个对应一个模板参数。

class ClassTemplate {
private:
T var1;
U var2;
V var3;
... .. ...
... .. ...
};

main()中,我们使用以下代码创建了两个ClassTemplate的对象

// 创建具有int、double和char类型的对象
ClassTemplate<int, double> obj1(7, 7.7, 'c');

// 创建具有double、char和bool类型的对象
ClassTemplate<double, char, bool> obj2(8.8, 'a', false);

这里,

对象TUV
obj1intdoublechar
obj2doublecharbool

对于obj1,T = intU = doubleV = char

对于obj2,T = doubleU = charV = bool