Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C+;中何时生成默认构造函数+; P>“内部C++对象模型”,只有当下面的四个条件中至少有一个是真的时,编译器才生成复制构造函数(如果程序员没有声明):_C++ - Fatal编程技术网

C+;中何时生成默认构造函数+; P>“内部C++对象模型”,只有当下面的四个条件中至少有一个是真的时,编译器才生成复制构造函数(如果程序员没有声明):

C+;中何时生成默认构造函数+; P>“内部C++对象模型”,只有当下面的四个条件中至少有一个是真的时,编译器才生成复制构造函数(如果程序员没有声明):,c++,C++,当类包含存在副本构造函数的类的成员对象时(由类设计器显式声明,如前一个字符串类,或由编译器合成,如Word类) 当类派生自存在副本构造函数的基类时(同样,显式声明或合成) 当类声明一个或多个虚拟函数时 从继承链派生类时,其中一个或多个基类是虚拟的 这意味着,如果我有一个只有构造函数的类,那么编译器将不会提供复制构造函数 让我们举一个例子: class test { test(){} }; int main() { test obj1; //statement 1

当类包含存在副本构造函数的类的成员对象时(由类设计器显式声明,如前一个字符串类,或由编译器合成,如Word类)

  • 当类派生自存在副本构造函数的基类时(同样,显式声明或合成)

  • 当类声明一个或多个虚拟函数时

  • 从继承链派生类时,其中一个或多个基类是虚拟的

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

    让我们举一个例子:

    class test
    {
        test(){}
    };
    int main()
    {
        test obj1;       //statement 1
        test obj2(obj1); //statement 2
    }
    
    以上代码工作正常。现在,当我在类测试中添加以下行时,问题出现了:

    test(const test& rhs) = delete;
    
    “=删除”确保不会自动提供复制构造函数。在添加上面的行之后,我得到了语句2的一个错误,它说
    使用删除的函数test::test(const test&)

    我的问题是:根据“内部C++对象模型”,我不需要为上面的类创建一个复制构造函数,所以当我明确地表示不生成一个复制构造函数(使用Delphi)时,为什么我会得到一个错误?因为我希望编译器不需要为上面的类使用复制构造函数

    我使用的是gcc版本4.6.3。

    这一行:

    test obj2(obj1)
    
    正在尝试调用复制构造函数。

    此行:

    test obj2(obj1)
    

    正在尝试调用复制构造函数。

    要使类可复制,它需要有一个复制构造函数。无论您是编写自己的,还是编译器为您生成一个,这都无关紧要——它必须可用于
    测试a;试验b(a)将成为有效的操作


    您显式地强制编译器删除复制构造函数-这是旧的“使复制构造函数私有”技巧的新版本。它不允许复制。所以,不要惊讶于你不能复制。因为您告诉编译器不允许它。

    要使类可复制,它需要有一个复制构造函数。无论您是编写自己的,还是编译器为您生成一个,这都无关紧要——它必须可用于
    测试a;试验b(a)将成为有效的操作


    您显式地强制编译器删除复制构造函数-这是旧的“使复制构造函数私有”技巧的新版本。它不允许复制。所以,不要惊讶于你不能复制。因为您告诉编译器不允许它。

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

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

    和[class.copy]/13:

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


    因此,
    test
    仍然会生成一个拷贝构造函数,它将被语句2调用。我相信“C++内部对象模型”是指当复制构造函数不是微不足道的时候。

    < P>隐式复制复制构造函数的标准字是[Copy.Reope]/7:

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

    和[class.copy]/13:

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


    因此,
    test
    仍然会生成一个拷贝构造函数,它将被语句2调用。我相信“C++内部对象模型”是在复制构造函数不是微不足道的时候讨论的。

    如果没有提供复制构造函数,那么语句2就不会编译。如果在类中不添加测试(const test和rh),它就可以正常工作。语句2不使用默认构造函数,它使用复制构造函数,如果您声明并删除了它(您这样做了),那么它将无法编译,因为语句2与已删除的签名匹配。您应该查看本书中的引用,因为您复制的版本不正确。如果这本书真的这么说的话,那么它就是错误的。如果你使用的是一个被删除的构造函数,那么你使用的是C++11,我很确定这本书没有一个版本涵盖C++11。有关何时隐式定义复制构造函数的规则已更改。也就是说,您引用的规则看起来像是C++03中非平凡副本的规则。隐式声明的复制构造函数在使用时隐式定义,