模板并在类构造函数中使用(#define)

时间:2016-05-25 05:06:51

标签: c++ class templates constructor default-arguments

我已经实现了堆栈进程。这个程序应该与真正的堆栈内存完全相同。而且我正在尝试使用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的地方。

3 个答案:

答案 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)中提到了

  

对于非模板函数,可以在稍后的同一范围内的函数声明中添加默认参数。

因此您无法在定义中指定默认值。这就是没有采用第二种方法的原因。

虽然第一种方法可以正常工作,但您可以省略定义中的默认值。