C++—类模板—Class template的使用

C++ 类模板是一种特殊类型的模板,用于定义类的行为,而不是定义特定的数据类型。通过使用类模板,你可以编写与特定数据类型无关的代码,并在后续实例化模板时指定具体的数据类型。这样,你可以创建适用于多种数据类型的类,而无需为每种数据类型都编写一个单独的类。

#include <bits/stdc++.h>
template <typename T>  
class MyArray {  
private:  
    T* arr;  
    int size;  
  
public:  
    MyArray(int s);  
    ~MyArray();  
    void set(int index, T value);  
    T get(int index);  
};  
  
template <typename T>  
MyArray<T>::MyArray(int s) {  
    size = s;  
    arr = new T[s];  
}  
  
template <typename T>  
MyArray<T>::~MyArray() {  
    delete[] arr;  
}  
  
template <typename T>  
void MyArray<T>::set(int index, T value) {  
    if(index >= 0 && index < size) {  
        arr[index] = value;  
    }  
}  
  
template <typename T>  
T MyArray<T>::get(int index) {  
    if(index >= 0 && index < size) {  
        return arr[index];  
    } else {  
        throw std::out_of_range("Index out of range");  
    }  
}
//参数部分
int main() {  
    MyArray<int> intArray(10);  
    intArray.set(0, 42);  
    std::cout << intArray.get(0) << std::endl;  
  
    MyArray<double> doubleArray(5);  
    doubleArray.set(0, 3.14);  
    std::cout << doubleArray.get(0) << std::endl;  
  
    return 0;  
}

在这个示例中,我们定义了一个名为 MyArray 的类模板,它接受一个类型参数 TMyArray 类用于表示一个动态数组,其中的元素类型为 T

  • MyArray 类有一个私有成员变量 arr,它是一个指向 T 类型数组的指针,以及一个整数 size,表示数组的大小。
  • 构造函数 MyArray(int s) 接收一个整数参数 s,用于初始化数组的大小,并分配相应的内存。
  • 析构函数 ~MyArray() 用于释放之前分配的内存。
  • set 成员函数用于设置数组中指定索引位置的值。
  • get 成员函数用于获取数组中指定索引位置的值。

注意,类模板的定义通常放在一个头文件中,这样当其他代码包含这个头文件时,编译器可以看到模板的定义,并可以实例化模板。

 

#include <bits/stdc++.h>
template <class numtype>
class Compare
{
	public:
		Compare(numtype a,numtype b)
		{
			x = a;
			y = b;
		}
		numtype max()
		{
			return (x > y)? x : y;
		}
		numtype min()
		{
			return (x < y)? x : y;
		}
	private:
		numtype x , y;
};
int main ()
{
	Compare<int>cmp1(3,7);
	std::cout<<cmp1.max()<<"is the Maxinum of two integer numbers."<<std::endl;
	std::cout<<cmp1.min()<<"is the Mininum of two integer numbers."<<std::endl<<std::endl;
	Compare<double>cmp2(28.2,73.2);
	std::cout<<cmp2.max()<<"is the Maxinum of two integer numbers."<<std::endl;
	std::cout<<cmp2.min()<<"is the Mininum of two integer numbers."<<std::endl<<std::endl;
	Compare<char>cmp3('a','A');
	std::cout<<cmp3.max()<<"is the Maxinum of two integer numbers."<<std::endl;
	std::cout<<cmp3.min()<<"is the Mininum of two integer numbers."<<std::endl<<std::endl;
	return 0;
}

函数类型暂定为numtype,在定义对象时如

	Compare<int>cmp1(3,7);

进行编译时就会将类模板中的虚拟类型名numtype全部用实际的类型替代。

在使用C++类模板时,有几个关键的注意事项需要牢记:

  1. 类型参数(Type Parameters)
    • 类模板使用类型参数来定义可以适用于多种数据类型的类。类型参数通常在模板声明中使用 typename 或 class 关键字来指定。
    • 模板类型参数可以是任何合法的C++类型,包括内置类型、用户定义的类型、指针类型等。
  2. 实例化(Instantiation)
    • 类模板本身并不生成类或对象代码,只有当模板被实例化时,编译器才会生成相应的类或对象代码。
    • 实例化可以通过在模板名后添加尖括号中的类型参数来完成,例如 MyArray<int> 或 MyArray<double>
  3. 成员函数定义的位置
    • 如果类模板的成员函数定义在类模板声明之外,那么这些成员函数的定义也需要使用 template <typename T> 来指明它们属于哪个模板。
    • 如果成员函数定义在类模板声明内部,则不需要再次指定 template <typename T>
  4. 编译时生成代码
    • 对于每种不同的类型参数,编译器都会生成独立的代码。这可能导致编译时间增加,特别是当使用大量不同的类型参数实例化模板时。
    • 由于生成的代码是独立的,模板实例化之间不会共享代码,这可能导致代码膨胀。
  5. 默认类型参数
    • 类模板可以具有默认类型参数,这使得在实例化模板时可以省略某些类型参数。
    • 默认类型参数提供了一种灵活性,允许用户根据需要提供部分或全部类型参数。
  6. 模板特化(Template Specialization)
    • 模板特化允许为特定的类型参数提供定制的模板实现。
    • 这对于处理某些特殊类型或优化特定类型的性能非常有用。
  7. 非类型模板参数
    • 除了类型参数外,C++还支持非类型模板参数,如整数常量或指针。
    • 非类型模板参数在某些情况下非常有用,但需要注意它们的限制和约束。
  8. 名字解析和依赖类型
    • 在模板中,特别是在涉及到嵌套模板或复杂类型时,名字解析可能会变得复杂。
    • 依赖类型(即依赖于模板参数的类型)也可能导致一些不易察觉的问题,因为它们可能不在模板定义的上下文中完全可见。
  9. 类型推导
    • 当使用自动类型推导(如auto关键字)与模板时,需要特别注意推导出的类型是否与模板的期望类型匹配。
  10. 错误处理
    • 由于模板是在编译时展开的,因此任何与类型不匹配或不符合模板约束的错误都将在编译时捕获。
    • 这要求开发者对类型系统和模板约束有深入的理解,以便能够正确诊断和解决编译时错误。

在使用类模板时,理解这些注意事项并遵循最佳实践可以帮助你更有效地利用模板,并避免常见的错误和问题。

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值