模板有两类:函数模板和类模板。学习模板必须区分模板的实例化和具体化,实例化函数用template关键字,具体化函数用template<>关键字。
隐式实例化:在调用模板函数时自动将类型填充,根据通用模板生成定义。
显式实例化:用关键字template,如:template class Arrytp<string ,100>;编译器会根据类型在通用模板生成。
显式具体化:特定的类型的定义,不是根据通用模板生成!
c++也支持部分具体化。可以只具体化其中的参数,不必全部具体化参数。
需要注意的是:在同一编译单元中对同一模板函数使用同一种类型进行实例化和具体化将会出错。
类模板与函数模板声明相似,但类模板包含比函数模板多。本文重点讨论类模板的指针使用。
例子:
我们创建了一个类模板如:
template Stack< typename type>
{
private:
string po;
.......
};
当我们想把type具体化为char *时;
版本1.
string po:
替换为:
char *po;
旨在用指针 来存储键盘输入,这种方法将会出错。因为仅仅创建了指针,没有创建用于保存字符的空间。
版本2.
string po;
替换为:
char po[40];
这里的po分配了空间,但却与方法中的数组使用不一致:
template <typename type>
bool Stack<type>::pop(type &item)
{
if(top>0)
{
item=item[--top];
return true;
}
else
return false;
}
首先item为类型名,而不能为数组名,其次假设可以为item赋值,item也能引用数组,但不能为数组名字赋值!
版本3.
string po;
char * po=new char[40];
这里的po分配空间了,也与方法中的使用一致了。
但只有一个pop变量,改变量总是指向相同的地址,所以每次进出栈的地址是相同的,堆栈就没有任何作用了(所有操作都在一个地址进行)。
如何真确地使用指针堆栈?
使用指针堆栈的方法之一:让调用程序提供一个指针数组,其中每个指针指向不同宝贵的字符串。
隐式实例化:在调用模板函数时自动将类型填充,根据通用模板生成定义。
显式实例化:用关键字template,如:template class Arrytp<string ,100>;编译器会根据类型在通用模板生成。
显式具体化:特定的类型的定义,不是根据通用模板生成!
c++也支持部分具体化。可以只具体化其中的参数,不必全部具体化参数。
需要注意的是:在同一编译单元中对同一模板函数使用同一种类型进行实例化和具体化将会出错。
类模板与函数模板声明相似,但类模板包含比函数模板多。本文重点讨论类模板的指针使用。
例子:
我们创建了一个类模板如:
template Stack< typename type>
{
private:
string po;
.......
};
当我们想把type具体化为char *时;
版本1.
string po:
替换为:
char *po;
旨在用指针 来存储键盘输入,这种方法将会出错。因为仅仅创建了指针,没有创建用于保存字符的空间。
版本2.
string po;
替换为:
char po[40];
这里的po分配了空间,但却与方法中的数组使用不一致:
template <typename type>
bool Stack<type>::pop(type &item)
{
if(top>0)
{
item=item[--top];
return true;
}
else
return false;
}
首先item为类型名,而不能为数组名,其次假设可以为item赋值,item也能引用数组,但不能为数组名字赋值!
版本3.
string po;
char * po=new char[40];
这里的po分配空间了,也与方法中的使用一致了。
但只有一个pop变量,改变量总是指向相同的地址,所以每次进出栈的地址是相同的,堆栈就没有任何作用了(所有操作都在一个地址进行)。
如何真确地使用指针堆栈?
使用指针堆栈的方法之一:让调用程序提供一个指针数组,其中每个指针指向不同宝贵的字符串。