在= delete的含义中使用= default

时间:2017-12-27 11:20:53

标签: c++ c++11 default-constructor

以下代码编译得很好:

struct B { 
    B(int) {} 
};

struct D : B {
    D() = default;
};

在我必须创建类D的实例之前:

D d; // error: use of deleted function 'D::D()'

= default的{​​{1}}构造函数是否允许D有什么理由(用例)吗?

3 个答案:

答案 0 :(得分:12)

g++在错误中给出了一个很好的解释:

  

bla.cpp:6:5:注意:'D :: D()'被隐式删除,因为默认定义不正确:        D()=默认;

默认构造函数将尝试构造D的所有部分。您没有字段,但它有一个初始B - 没有空构造函数,只有一个int

默认行为是有道理的 - D不应该有一个空的构造函数,除非它明确说明构造int的{​​{1}},并且编译器不想猜测。否则,您将拥有B对象,并且取决于D构造函数B中发生的事件可能包含垃圾,例如,如果初始化字段。

当你问为什么这是“允许”时,我不确定你是否真正意味着你的问题,因为删除了B默认构造函数,但我可以想到两个原因:

  1. 此行为已明确定义,并且没有理由不允许它。无论如何,只有在您尝试非法构建某些内容时才会检测到错误。
  2. 更灵活 - 将B更改为默认构造函数会自动允许B拥有一个。

答案 1 :(得分:6)

  

是否有任何理由(用例)允许= D的构造函数的默认值,当它实际上工作为= delete;?

它不能用作PrintOut。它说它应该说什么。您明确希望编译器生成默认实现。

恰好,编译器生成的一个必须被定义删除。因为隐式删除了=delete的默认构造函数。

答案 2 :(得分:1)

B有一个非默认的构造函数(它的构造函数接受一个没有默认值的参数)。

派生的D类因此没有默认构造函数,其默认构造函数被删除(因为编译器无法为D生成可以调用B(int)构造函数的构造函数其父类。)

D() = default;只是说你想要D的默认构造函数,如上所述,默认构造函数被删除。