我正在阅读Generic Classes主题。我一度陷入困境。以下是一段代码
template <class StackType> class stack
{
StackType stck[10];
int tos;
public:
stack() {tos=0;}
void push(StackType ob);
StackType pop();
};
我的问题是template <class StackType> class stack
,
有两个课程(StackType
和stack
)?
我的意思是编译器如何将其视为使堆栈成为StackType的嵌套类或其他东西?
答案 0 :(得分:8)
它不是创建第二个类,而是创建一个Stack类型的类,其中StackType被用户给定的类型取代。定义它的更好方法是使用typename(§14.1.2),这样可以更清楚地了解实际情况。有关模板的更多信息,请参阅C++ Templates。
您所描述的是模板中的嵌套类:
template <typename Type>
class Stack
{
public:
class InnerType
{
};
};
在此示例中,InnerType是一个强名称为Stack<Type>::InnerType
的类,它是基于提供的类型的特定类。因此,如果代码中的某个位置创建了一个对象:
auto x = new Stack<int>();
然后将存在类Stack<int>::InnerType
的类。模板类仅在代码中使用时才存在于程序集中,因此如果没有实现任何Stack
变体的对象,InnerType
(任何模板类型)都不会存在。
关于声明模板的更多详细信息是discussed here on SO。
答案 1 :(得分:3)
没有第二堂课。 StackType
是模板参数。您可以在考虑具有一个参数的函数的参数时考虑它。除非调用并提供其参数,否则该函数无法执行任何操作。与模板类StackType
相同,它是模板类型stack
的类型参数。当您提供类型[name]作为模板类的参数时,专门化模板类。所有这些提供和专业化的论点都发生在编译时。例如,第一次编译器遇到像
堆&LT; int&gt; stackVariable;
或
typedef stack&lt; int&gt; StackOfInts;
只有这样才能实际编译并实例化一个名为stack< int >
的类型 - 一堆整数。直到那一刻,没有任何东西堆叠。
使用int
进行实例化后,您的班级将成为:
template<>
class stack< int >
{
int stck[10];
int tos;
public:
stack() {tos=0;}
void push(int ob);
int pop();
};
答案 2 :(得分:2)
class
内的<>
与外界的含义不同。它与typename
基本相同。
答案 3 :(得分:2)
所以模板不是一个类。这是模板从用户定义的类型(例如int)创建类的一种方式。所以当我说:
stack<int>
编译器从您的类生成一个类stack < int >
,基本上用StackType
填充int
并编译该类。
所以,如果我做了一个:
stack<stack<int> >
编译器将生成两个类stact < int >
和 stack < stack < int > >
答案 4 :(得分:1)
模板创建了一个类系列 - 每个类都具有相同的功能,但可以在不同的类型上运行。
在您的示例中,它正在创建一个类系列。例如X类堆栈,Y类堆栈等。