73.C++类模板

类模板的定义

类模板(Class Template)是C++中一种强大的特性,它允许创建可以适用于不同数据类型的通用类。类模板是用于生成类的模板,其中的数据类型可以在实例化时指定。

        类模板和函数模板的定义和使用基本是一样的,如何定义函数模板,就如何定义类模板。但是类模板与函数模板还是有点区别的:

类模板不能自动推导类型。

template
class NumberOperator {
public:
	T1 num1;
	T2 num2;

	void cal() {
		cout << num1 + num2 << endl;
	}
};

int main() {

	//创建对象,不能类型推导,只能自己指定类型
	NumberOperator op1;
	op1.num1 = 10;
	op1.num2 = 20;
	op1.cal();

	//创建对象
	NumberOperator op2;
	op2.num1 = 3.14;
	op2.num2 = 10;
	op2.cal();

	return 0;
}

这段代码演示了使用类模板 NumberOperator 来创建具有不同数据类型的对象。NumberOperator 类模板允许您定义两个模板参数 T1T2,其中 T2 默认为 int 类型。这样,您可以根据需要选择性地指定类型,或者使用默认类型。

main 函数中,我们创建了两个不同类型的 NumberOperator 对象:

  1. op1 是一个 NumberOperator 对象,其中 T1T2 都被指定为 int 类型。我们设置了 num1num2 的值,然后调用 cal 函数来计算它们的和,并输出结果。

  2. op2 是另一个 NumberOperator 对象,这次我们只指定了 T1double 类型,而 T2 使用了默认的 int 类型。同样,我们设置了 num1num2 的值,然后调用 cal 函数来计算它们的和,并输出结果。

类模板做函数参数

template
class NumberOperator {
public:
	T1 num1;
	T2 num2;

	void cal() {
		cout << num1 + num2 << endl;
	}
};

//参数中明确模板类
void useNumberOperation(NumberOperator& op) {
	op.cal();
}

//参数中使用模板
template
void useNumberOperation02(NumberOperator& op) {
	op.cal();
}
int main() {

	//参数明确模板类调用
	NumberOperator op1;
	op1.num1 = 10;
	op1.num2 = 20;
	useNumberOperation(op1);

	//创建对象
	NumberOperator op2;
	op2.num1 = 3.14;
	op2.num2 = 10;
	useNumberOperation02(op2);

	return 0;
}

这段代码演示了如何使用参数中明确模板类或使用模板参数的方式来调用 NumberOperator 类模板的成员函数。这允许在不同的上下文中使用模板类。

在这个代码中:

  1. useNumberOperation 函数的参数 op 是一个明确指定了模板参数类型的 NumberOperator 类对象。这里我们明确指定了 T1T2int 类型。然后,我们调用 op.cal() 来计算并输出结果。

  2. useNumberOperation02 函数使用了模板参数 T1T2。这意味着您可以在调用时根据需要指定模板参数类型。在 main 函数中,我们创建了一个 NumberOperator 对象 op2,其中 T1 明确指定为 double 类型,而 T2 使用默认的 int 类型。然后,我们使用 useNumberOperation02(op2) 调用该函数,它会计算并输出结果。

类模板继承

//定义模板类
template
class Animal {
public:
	T arg;
};

//普通类继承模板类的时候,必须明确指定类型
class Dog :Animal {
	//这里继承到的arg的数据类型是int
};

template
class Person :Animal {
	//这里继承到得arg的数据类型是E
};

 

您提供的代码示例演示了如何定义一个模板类 Animal,以及如何创建普通类 DogPerson 来继承这个模板类。

  1. Animal 是一个模板类,它拥有一个模板类型参数 T,该参数可以用于定义类中的成员。

  2. Dog 是一个普通类,通过 class Dog : Animal 继承了模板类 Animal,并明确指定了类型参数为 int。这意味着 Dog 类中的 arg 成员的数据类型是 int

  3. Person 也是一个模板类,它继承了模板类 Animal,但没有明确指定类型参数,而是使用了 E 作为类型参数。这使得 Person 类中的 arg 成员的数据类型取决于在实例化 Person 类时传递的类型参数 E

类模板类外实现

template
class NumberCalculator {
private:
	T n1;
	M n2;
public:
	NumberCalculator() {}
	NumberCalculator(T n1, M n2);

	void add();
};
// 构造函数类外实现
template
NumberCalculator::NumberCalculator(T n1, M n2) {
	this->n1 = n1;
	this->n2 = n2;
}
// 普通函数类外实现
template
void NumberCalculator::add() {
	cout << n1 + n2 << endl;
}

 类模板遇到友元函数

#include 

using namespace std;

// 全局友元函数类外实现-03:定义类
template
class NumberCalculator;
// 全局友元函数类外实现-02:在类之前定义
template
void printNumberCalculator(const NumberCalculator& op) {
	cout << "n1 = " << op.n1 << ", n2 = " << op.n2 << endl;
}
template
class NumberCalculator {
	// 全局友元函数类内实现,⽆需进⾏什么处理,直接在这⾥写实现即可。
    /* friend void printNumberCalculator(const NumberCalculator& op) {
     cout << "n1 = " << op.n1 << ", n2 = " << op.n2 << endl;
      }*/
	// 全局友元函数类外实现—01:在函数的后⾯添加⼀对尖括号,表示⼀个模板函数
	friend void printNumberCalculator<>(const NumberCalculator& op);
private:
	T n1;
	M n2;
public:
	NumberCalculator();
	NumberCalculator(T n1, M n2);
};
template
NumberCalculator::NumberCalculator(T n1, M n2) {
	this->n1 = n1;
	this->n2 = n2;
}
template
NumberCalculator::NumberCalculator() = default;
int main() {
	NumberCalculator op(10, 20);
	printNumberCalculator(op);
	return 0;
}

这段代码演示了如何使用友元函数来访问类模板 NumberCalculator 中的私有成员。友元函数可以访问类的私有成员,即使这些私有成员的数据类型是模板参数。

以下是代码的解释:

  1. 在代码中,首先定义了一个类模板 NumberCalculator,它具有两个模板类型参数 TM,表示类的两个私有成员 n1n2 的数据类型。

  2. 在全局范围内定义了一个友元函数 printNumberCalculator,该函数接受一个 NumberCalculator 对象作为参数,并用于输出对象的私有成员 n1n2 的值。

  3. 在类模板内,通过 friend 关键字声明 printNumberCalculator 为类模板 NumberCalculator 的友元函数。在这种情况下,您需要提供额外的 <> 尖括号,以告诉编译器这是一个模板函数。

  4. main 函数中,我们创建了一个 NumberCalculator 对象 op,并调用 printNumberCalculator(op) 来输出 op 对象的私有成员。

你可能感兴趣的:(C++,c++,开发语言)