类模板

自我总结,若有问题欢迎指出!谢谢。

1 语法

下面是类模板的基本语法

template<class T>
类定义

其中,中的“class”也可以替换成“typename”,只是为了 告诉编译器后面接的是某一个待传入的数据类型T。

举个例子,下面声明一个数组类的模板,数组中元素的数据类型为T,

// MyArray.hpp
template<class T>
class MyArray
{
public:
	MyArray(int cap)
	{
		m_arrAddress = new T[cap];
		m_capacity = cap;
		m_size = 0;
	}
	~MyArray()
	{
		if (m_arrAddress != NULL)
		{
			delete[] m_arrAddress;
			m_arrAddress = NULL;
		}
		m_capacity = 0;
		m_size = 0;
	}

private:
	T *m_arrAddress;
	int m_capacity; // 表示数组最大空间
	int m_size;// 表示数组当前空间
};

2 基本用法

继承上面所声明的数组类模板,我们现在想声明一个整型数组,即

#include "MyArray.hpp"
int main()
{
	MyArray<int> arr(10); // 声明了一个数组大小为10的整型数组
	return 0;
}

3注意

(1)没有为类成员传入具体数据类型的模板类,其不是一个真正意义上的类,只是一个模板,因此不能进行变量声明,即

MyArray arr(10); // false!
MyArray<int> arr(10);  // true!

(2)类模板中如果成员函数的返回值是也是一个类模板,则一定要说明类成员数据类型(int/double/自定义数据类型/…)

举个例子:

// MyArray.hpp
template<class T>
class MyArray
{
public:
	MyArray(int cap)
	{
		m_arrAddress = new T[cap];
		m_capacity = cap;
		m_size = 0;
	}
	
	~MyArray()
	{
		if (m_arrAddress != NULL)
		{
			delete[] m_arrAddress;
			m_arrAddress = NULL;
		}
		m_capacity = 0;
		m_size = 0;
	}

	// 注意到,返回类型时MyArray<T>
	MyArray<T>& operator=(const MyArray& arr)
	{
		if (this->m_arrAddress != NULL)
		{
			delete[] this->m_arrAddress;
			this->m_arrAddress = NULL;
		}
	
		this->m_arrAddress = new T[arr.m_capacity]; // 深拷贝
		this->m_size = arr.m_size;
		this->m_capacity = arr.m_capacity;
	
		for (int i = 0; i < this->m_size; i++)
		{
			this->m_arrAddress[i] = arr.m_arrAddress[i];
		}
	}

private:
	T *m_arrAddress;
	int m_capacity; // 表示数组最大空间
	int m_size;// 表示数组当前空间
};

由上面的例子可见,当我们重载运算符“=”时,返回类型是MyArray&。
这时候有人会问,我写成MyArray&编译也没有报错,咋回事?
这个应该是编译器(我是VS2019)替我们做了优化,即在成员函数类内实现 时,如果返回值为本类的类型,可以不用加。但如果类外实现的时候,编译就会报错了!即,

// MyArray.hpp
template<class T>
class MyArray
{
public:
	MyArray(int cap)
	{
		m_arrAddress = new T[cap];
		m_capacity = cap;
		m_size = 0;
	}
	~MyArray()
	{
		if (m_arrAddress != NULL)
		{
			delete[] m_arrAddress;
			m_arrAddress = NULL;
		}
		m_capacity = 0;
		m_size = 0;
	}

	MyArray& operator=(const MyArray& arr);

private:
	T *m_arrAddress;
	int m_capacity; // 表示数组最大空间
	int m_size;// 表示数组当前空间
};

// 类外实现
template<class T>
MyArray& MyArray<T>::operator=(const MyArray& arr) //  false!
{
	if (this->m_arrAddress != NULL)
	{
		delete[] this->m_arrAddress;
		this->m_arrAddress = NULL;
	}

	this->m_arrAddress = new T[arr.m_capacity];
	this->m_size = arr.m_size;
	this->m_capacity = arr.m_capacity;

	for (int i = 0; i < this->m_size; i++)
	{
		this->m_arrAddress[i] = arr.m_arrAddress[i];
	}
}

template<class T>
MyArray<T>& MyArray<T>::operator=(const MyArray& arr) // true!
{
	if (this->m_arrAddress != NULL)
	{
		delete[] this->m_arrAddress;
		this->m_arrAddress = NULL;
	}

	this->m_arrAddress = new T[arr.m_capacity];
	this->m_size = arr.m_size;
	this->m_capacity = arr.m_capacity;

	for (int i = 0; i < this->m_size; i++)
	{
		this->m_arrAddress[i] = arr.m_arrAddress[i];
	}
}

4 总结

对于类模板的使用,没有声明成员数据类型,则永远只是个模板,可以视作为一个“抽象”的类。只有声明了数据类型,才是一个 真正的类!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值