何时在C ++中生成默认构造函数

时间:2012-06-01 17:41:24

标签: c++

根据“Inside C ++ Object Model”,只有当以下四个条件中的任何一个条件成立时,编译器才会生成复制构造函数(如果程序员没有声明):

  1. 当类包含存在复制构造函数的类的成员对象时(由类设计器显式声明,如前一个String类的情况,或由编译器合成,如类Word的情况)

  2. 当类派生自存在复制构造函数的基类时(同样,显式声明或合成)

  3. 当类声明一个或多个虚函数

  4. 当类派生自一个或多个基类为虚拟的继承链时

  5. 这意味着如果我有一个只有构造函数的类,那么编译器将不会提供复制构造函数。

    让我们举一个例子:

    class test
    {
        test(){}
    };
    int main()
    {
        test obj1;       //statement 1
        test obj2(obj1); //statement 2
    }
    

    以上代码工作正常。现在问题出现在我在类测试中添加以下行:

    test(const test& rhs) = delete;
    

    “= delete”确保不会自动提供复制构造函数。在添加上面一行后,我收到一条错误,声明为Use of deleted function test::test(const test&)

    我的问题是:根据“内部C ++对象模型”,我不需要上述类的复制构造函数,所以当我明确说不生成复制构造函数(使用删除)时,为什么会出现错误?因为我期望编译器不需要上面类的复制构造函数。

    我正在使用gcc版本4.6.3。

3 个答案:

答案 0 :(得分:8)

对于可复制的类,它需要有一个复制构造函数。无论您是自己编写,还是编译器为您生成一个,都无关紧要 - 它必须可用于test a; test b(a);才能成为有效的操作。

您明确强制编译器删除复制构造函数 - 这是旧版“make copy constructor private”的新版本。它不允许复制。所以不要惊讶你不能复制。因为你告诉编译器不允许它。

答案 1 :(得分:2)

隐式生成的复制构造函数的标准词是 [class.copy] / 7

  

如果类定义没有显式声明复制构造函数,则会隐式声明一个。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数被定义为已删除;否则,它被定义为默认值(8.4)。如果类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况。

[class.copy] / 13

  

如果使用了odr-used(3.2)或者在第一次声明后显式默认,则默认定义一个默认且未定义为已删除的复制/移动构造函数。 [注意:即使实现省略了odr-use(3.2,12.2),也会隐式定义复制/移动构造函数。 -end note]如果隐式定义的构造函数满足constexpr构造函数(7.1.5)的要求,则隐式定义的构造函数isconstexpr。

因此仍然为test生成了 copy-constructor ,并且它被语句2调用。我相信“内部C ++对象模型”正在谈论何时 copy-constructor 并非易事。

答案 2 :(得分:0)

这一行:

test obj2(obj1)

正试图调用复制构造函数。

相关问题