我已经实现了堆栈进程。这个程序应该与真正的堆栈内存完全相同。而且我正在尝试使用Template并使程序更通用。我在使用#define DEFAULT_SIZE 10
作为类构造函数的参数时遇到了问题。
首先,当我将DEFAULT_SIZE
放在构造函数的原型中时,它顺利进行:
#define DEFAULT_SIZE 10
template<typename T>
class stack {
public:
stack(int size=DEFAULT_SIZE);
private:
T *elements;
int size;
int count;
};
template<typename T>
stack<T>::stack(int s) {
cout << "--constructor called\n";
size = s;
elements = new T[size];
count = 0;
}
但是当我把DEFAULT_SIZE
放在类构造函数的大纲定义中时,我得到了这个错误:no appropriate default constructor available
#define DEFAULT_SIZE 10
template<typename T>
class stack {
public:
stack(int size);
private:
T *elements;
int size;
int count;
};
template<typename T>
stack<T>::stack(int s=DEFAULT_SIZE) {
cout << "--constructor called\n";
size = s;
elements = new T[size];
count = 0;
}
最后是该计划的主要内容:
int main() {
stack<int> u;
u.push(4);
}
我的问题不是“为什么模板只能在头文件中实现?”我的问题是我使用DEFAULT_SIZE
的地方。
答案 0 :(得分:2)
我想,问题在于模板声明的区别:
stack(int size);
和模板定义:
stack<T>::stack(int s=DEFAULT_SIZE) {
...
}
默认值必须在声明部分,如果定义中的方法签名与声明不同(在定义中添加DEFAULT_SIZE),编译器不确定您是否编写相同的构造函数。注意,当DEFAULT_SIZE
值未赋予构造函数时,将应用s
,因此您的定义将作为默认构造函数使用,但声明是具有一个参数的构造函数。
答案 1 :(得分:1)
如果您使用Ideone编译第二个代码段,例如它为您提供“重新声明的'stack :: stack(int)'可能没有默认参数”(请参阅http://ideone.com/UKIx2r)
prog.cpp:16:35: error: redeclaration of 'stack<T>::stack(int)' may not have default arguments [-fpermissive]
stack<T>::stack(int s=DEFAULT_SIZE) {
必须在第一个声明中指定默认参数
如果声明自己的构造函数,则将删除默认构造函数。但是,只要所有参数都具有默认值,您的构造函数就会充当默认构造函数。
您的第一部分声明了constructors参数的正确默认值。你的第二部分没有,你的编译器也没有机会将构造函数用作默认构造函数。
答案 2 :(得分:1)
在C ++规范(§8.3.6pt.4)中提到了
对于非模板函数,可以在稍后的同一范围内的函数声明中添加默认参数。
因此您无法在定义中指定默认值。这就是没有采用第二种方法的原因。
虽然第一种方法可以正常工作,但您可以省略定义中的默认值。