请看这段代码
class Bond
{
public:
Bond(int payments_per_year, int period_lengths_in_months);
Bond() = default;
private:
const int payments_per_year;
const int period_length_in_months;
};
int main()
{
Bond b; // Error here
}在试图编译时,我得到了一个错误:
错误C2280:'Bond::Bond(void)':试图引用已删除的函数“。
这不是违反“3的规则”,因为我已经添加了默认的构造函数。
为什么编译器不识别Bond() = default;
发布于 2018-11-09 14:07:20
您正在受到C++草案(或C++11中的[class.ctor]p5 )部分的影响,该节说:
在以下情况下,类X的默认构造函数被定义为已删除: .
解决问题的关键是使用没有大括号或等初始化器的短语,因此,如果您提供支撑式或等式初始化器来解决您的问题,例如:
const int payments_per_year{12};
const int period_length_in_months{48};支撑式或等式初始化器不需要大括号,我们可以看到这是语法:
brace-or-equal-initializer:
= initializer-clause
braced-init-list但是,使用统一初始化有一些优点,例如使变窄畸形值得使用它们。
gcc和clang都为这个看现场直播节目提供了更有意义的诊断。有时,在多个编译器上尝试代码可能会很有帮助,特别是如果您有这样一个最小的测试用例,例如clang说:
warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
Bond() = default;
^
note: default constructor of 'Bond' is implicitly deleted because field 'payments_per_year' of const-qualified type 'const int' would not be initialized
const int payments_per_year;
^
...发布于 2018-11-09 11:44:44
由于需要显式初始化的常量成员,默认构造函数将被抑制。
因此,由于这种抑制,编写Bond() = default不会重新引入默认构造函数。
(您可以通过移除类中的所有构造函数来看到这种效果--您仍然不能实例化b。)
如果您从成员中删除const,那么一切都会很好;尽管另一种选择是为每个const成员提供一个支撑或相等的初始化器;
const int payments_per_year = 2;
const int period_length_in_months = 6;例如。
发布于 2018-11-09 12:14:26
另一个解决方法是在常量声明中指定默认值:
const int payments_per_year = {12};这仍然可以被值构造函数覆盖,但允许默认构造函数继续进行。
这也是一种非常灵活的方法来简化多个构造函数的情况。
https://stackoverflow.com/questions/53225106
复制相似问题