类模板

113 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

一、类模板

💦 类模板的定义格式

template<class T1, class T2, ..., class Tn>
class 类模板名
{
 //类内成员定义
};

栈的泛型问题 ❓

typedef int STDataType;
class Stack
{
private:
	STDataType* _a;
	int _top;
	int _capacity;
};
int main()
{
	Stack st1;//int
	Stack st2;//double
	return 0;
}

📝说明

这里想让 st1 是 int,st2 是 double,显然这里做不到。C 语言中的 typedef 只是增强程序的可维护性,不能解决泛型的问题。

类模板解决栈泛型 ❓

struct TreeNode
{
	
};
template<class T>
class Stack
{
private:
	T* _a;
	int _top;
	int _capacity;
};
int main()
{
	Stack<TreeNode>st1;//TreeNode*
	Stack<int>st2;//int
	return 0;
}

📝说明

对于函数模板可以根据实参去推演形参的类型,但是类在用的时候,首先是定义对象,所以类模板的使用都是显示实例化。

Stack< TreeNode* >st1 和 Stack< int >st2 用的是一个类 ❓

它们的模板参数不同,用的不是同一个类。

调试后发现,st1 里的 _a 是 TreeNode* 类型, st2 里的 _a 是 int* 类型。

💦 类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。

//Stack类名,Stack<int>才是类型
Stack<int>s1;
Stack<double>s2;
struct TreeNode
{};
template<class T>
class Stack
{
public:
	Stack(int capacity = 4)
		: _a(new T[capacity])
		, _top(0)
		, _capacity(capacity)
	{}
	~Stack()
	{
		delete[]_a;
		_a = nullptr;
		_top = _capacity = 0;
	}
	//类里面声明,类外面定义呢???
	void Push(const T& x);
private:
	T* _a;
	int _top;
	int _capacity;
};
template<class T>
void Stack<T>::Push(const T& x)//指定域,且需要声明模板
{}
int main()
{
	Stack<TreeNode*>st1;//TreeNode*
	Stack<int>st2;//int
	return 0;
}

📝说明

在类模板里声明,类模板外定义,与以前的不同。

普通类,类名就是类型

类模板,类名不是类型,类型是 Stack

函数/类模板不支持把声明写到 .h,定义写到 .cpp 的方式,会报链接错误,原因后面会详细讲。

.h里实例化了,Stack.cpp里没有实例化,test.cpp去找的时候,只有声明,没有定义。所以解决方法就是声明和定义不要分离,当然要分离也有方法,但是这种方法比较 low,在模板的进阶会详细学习。

在这里插入图片描述