在 class 构造函数中模板和使用 (#define)
Template and using (#define) in class constructor
我已经实现了堆栈 process.this 程序应该与真正的堆栈完全相同 memory.moreover 我正在尝试使用模板并使程序更通用。我在使用 #define DEFAULT_SIZE 10
作为 class 构造函数的参数时遇到问题。
首先,当我将 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
放入 class 构造函数的大纲定义中时,我得到了这个错误: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);
}
我的问题不是关于"Why can templates only be implemented in the header file?"我的问题是我使用DEFAULT_SIZE
的地方。
我想,问题在于模板声明的不同:
stack(int size);
和模板定义:
stack<T>::stack(int s=DEFAULT_SIZE) {
...
}
默认值必须在声明部分,如果定义中的方法签名与声明不同(您在定义中添加 DEFAULT_SIZE)编译器不确定您是否编写了相同的构造函数。请注意,当 s
值未提供给构造函数时应用 DEFAULT_SIZE
,因此您的定义将用作默认构造函数,但声明是具有一个参数的构造函数。
如果你用 Ideone 编译你的第二个代码片段,它会给你“redeclaration of 'stack::stack(int)' may not have default arguments”(见 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) {
必须在第一个声明中指定默认参数
如果您声明自己的构造函数,默认构造函数将被删除。但是,只要所有参数都具有默认值,您的构造函数将充当默认构造函数。
您的第一部分声明了构造函数参数的正确默认值。你的第二部分没有,你的编译器没有机会使用构造函数作为默认构造函数。
C++ 规范(§8.3.6 pt.4)中提到
For non-template functions, default arguments can be added in later declarations of a function in the same scope.
所以不能在定义中赋默认值。这就是第二种方法不起作用的原因。
虽然第一种方法会起作用,因为它是您可以在定义中省略默认值的所需行为。
我已经实现了堆栈 process.this 程序应该与真正的堆栈完全相同 memory.moreover 我正在尝试使用模板并使程序更通用。我在使用 #define DEFAULT_SIZE 10
作为 class 构造函数的参数时遇到问题。
首先,当我将 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
放入 class 构造函数的大纲定义中时,我得到了这个错误: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);
}
我的问题不是关于"Why can templates only be implemented in the header file?"我的问题是我使用DEFAULT_SIZE
的地方。
我想,问题在于模板声明的不同:
stack(int size);
和模板定义:
stack<T>::stack(int s=DEFAULT_SIZE) {
...
}
默认值必须在声明部分,如果定义中的方法签名与声明不同(您在定义中添加 DEFAULT_SIZE)编译器不确定您是否编写了相同的构造函数。请注意,当 s
值未提供给构造函数时应用 DEFAULT_SIZE
,因此您的定义将用作默认构造函数,但声明是具有一个参数的构造函数。
如果你用 Ideone 编译你的第二个代码片段,它会给你“redeclaration of 'stack::stack(int)' may not have default arguments”(见 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) {
必须在第一个声明中指定默认参数
如果您声明自己的构造函数,默认构造函数将被删除。但是,只要所有参数都具有默认值,您的构造函数将充当默认构造函数。
您的第一部分声明了构造函数参数的正确默认值。你的第二部分没有,你的编译器没有机会使用构造函数作为默认构造函数。
C++ 规范(§8.3.6 pt.4)中提到
For non-template functions, default arguments can be added in later declarations of a function in the same scope.
所以不能在定义中赋默认值。这就是第二种方法不起作用的原因。
虽然第一种方法会起作用,因为它是您可以在定义中省略默认值的所需行为。