【问题标题】:Template and using (#define) in class constructor类构造函数中的模板和使用(#define)
【发布时间】:2016-09-22 12:46:11
【问题描述】:

我已经实现了堆栈进程。这个程序应该与真正的堆栈内存完全相同。此外,我正在尝试使用模板并使程序更通用。我在使用#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的地方。

【问题讨论】:

  • 请使用代码标题修复您的代码块。
  • 多谢提醒,问题清楚了吗?
  • 这段代码中的“没有合适的默认构造函数可用”错误是从哪里得到的?
  • 我在我写的行中得到错误 (stack u;)
  • Why can templates only be implemented in the header file?的可能重复基本上是把实现放在头文件中,而不是创建单独的实现文件。

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


【解决方案1】:

我想,问题只是模板声明的不同:

 stack(int size);

和模板定义:

stack<T>::stack(int s=DEFAULT_SIZE) {
   ...
}

默认值必须在声明部分,如果定义中的方法签名与声明不同(您在定义中添加 DEFAULT_SIZE)编译器不确定您是否编写相同的构造函数。请注意,DEFAULT_SIZE 是在 s 值未赋予构造函数时应用的,因此您的定义将作为默认构造函数工作,但声明是具有一个参数的构造函数。

【讨论】:

  • 你真是太好了。我明白了。
【解决方案2】:

在 C++ 规范(§8.3.6 pt.4)中提到

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

因此您不能在定义中分配默认值。这就是第二种方法不起作用的原因。

虽然第一种方法会起作用,但您可以在定义中省略默认值。

【讨论】:

  • 非常感谢。我明白了。但我不知道非模板函数是什么剂量??你解释一下可以吗???
  • 一个普通的类成员函数,它不是模板函数。更多信息请参考这篇文章link
【解决方案3】:

如果你用 Ideone 编译你的第二个代码 sn-p,它会给你“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) {

必须在第一个声明中指定默认参数

如果您声明自己的构造函数,则默认构造函数将被删除。但是,只要所有参数都具有默认值,您的构造函数就会充当默认构造函数。

您的第一部分为构造函数参数声明了正确的默认值。您的第二部分没有,您的编译器没有机会将构造函数用作默认构造函数。

【讨论】:

  • 我在我写的行中得到错误 (stack u;)
  • 我添加了我的答案来解释发生了什么
  • 非常感谢..多年来我一直在寻找答案。
  • 嗨@Kasra,如果这个或任何答案已经解决了您的问题,请考虑通过单击复选标记接受它。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。 (从 Ben meta.stackoverflow.com/a/251298/6172310 窃取的评论)
  • 注意:此规则仅适用于模板。非模板函数可能在重新声明中添加了默认参数。
猜你喜欢
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多