为什么删除成员变量的副本构造函数不会阻止默认的副本构造函数

时间:2019-04-15 00:51:48

标签: c++

class A {
public:
    A() = default;
    A(const A&) = delete;
    A(A&&) = delete;
};

class B {
public:
    B() = default;
    B(const B&) = default;
    B(B&&) = default;

    A a_;
};

int main() {
    B b{};
    static_cast<void>(b);
}

为什么要编译?复制构造函数不应具有默认定义,因为A具有已删除的拷贝构造函数。 在这种情况下,默认副本构造函数意味着什么? 我在这里想念什么?

2 个答案:

答案 0 :(得分:2)

将特殊成员声明为默认成员不会 not 表示存在可用的定义。相反,= default的意思是“在这里填写合理的含义”,这也意味着如果这是唯一合理的事情(例如,如果类成员不可复制),则该成员最终被定义为已删除。 / p>

确切的规则在[class.copy.ctor]中:

  

[...]如果X具有以下条件,则将类X的默认复制/移动构造函数定义为已删除(9.4.3):

     
      
  • 可能被构造的子对象类型M(或其数组),由于用于查找M的对应构造函数的重载分辨率(11.3)导致模棱两可或从默认构造函数中删除或无法访问的函数,
  •   
  • [...]
  •   

也就是说,您的B::B(const B&)最终被定义为已删除。尝试制作b的副本时,您会注意到这一点。

答案 1 :(得分:1)

这里的默认值表示我认为是删除。有人需要查找标准文档以进行确认。但是,如果您在main()中添加了一行B foo = b;,那么我肯定会开始出现编译器错误。尽管将default关键字用于复制ctor,您仍将无法复制B。

编辑:这是我尝试复制B时遇到的错误。

  

“ B :: B(const B&)”被隐式删除,因为默认定义   会格式错误

相关问题