【问题标题】:Do I still get default copy constructor and operator= if I define ones with non-const arguments?如果我用非常量参数定义了复制构造函数和 operator=,我还会得到默认的复制构造函数和 operator= 吗?
【发布时间】:2012-08-13 14:48:01
【问题描述】:

在 C++ 中,如果我定义了一个复制构造函数和 operator= 对类进行非常量引用,编译器是否仍应该为 const 引用提供默认版本?

struct Test {
  Test(Test &rhs);
  Test &operator=(Test &rhs);

private:
  // Do I still need to declare these to avoid automatic definitions?
  Test(const Test &rhs);
  Test &operator=(const Test &rhs);
};

【问题讨论】:

    标签: c++ constants language-lawyer default-copy-constructor


    【解决方案1】:

    不,如果您定义了复制构造函数和赋值运算符,编译器将不会隐式声明或定义它自己的。请注意,copy-constructor 的定义允许参数被 const 或非 const 引用采用,因此您的构造函数确实是 copy-constructoroperator= 也是如此

    [省略了很大一部分细节,特别是在什么情况下隐式声明的特殊成员函数也会被隐式定义]

    12.8 [class.copy]/2 类 X 的非模板构造函数是一个复制构造函数,如果它的第一个参数是 X&、const X&、volatile X& 或 const volatile X& 类型,并且要么没有其他参数,要么否则所有其他参数都有默认参数 (8.3.6)。

    12.8 [class.copy]/7 如果类定义没有显式声明复制构造函数,则隐式声明。

    12.8 [class.copy]/17 用户声明的复制赋值运算符 X::operator= 是类 X 的非静态非模板成员函数,只有一个 X、X&、const X&、volatile 类型的参数X& 或 const volatile X&。

    12.8 [class.copy]/18 如果类定义没有显式声明复制赋值运算符,则隐式声明一个。

    【讨论】:

      【解决方案2】:

      不,一旦您声明了自己的复制构造函数或复制赋值运算符(无论它是否使用规范的constness),编译器将不再为您执行此操作。

      但是通过非常量引用来执行此操作几乎是违反最小意外原则的教科书示例。每个人都希望可以分配 const 对象,并且右侧不会发生变异。第一个并没有那么糟糕,因为编译器会捕捉到它,但第二个可能会导致各种难以发现的错误。

      如果您尝试实现移动语义并且不能使用 C++11,我建议创建一个特殊的移动方法,并且根本不允许“移动”构造。如果您可以使用 C++11,请使用内置的右值引用。

      【讨论】:

        猜你喜欢
        • 2013-04-04
        • 2020-05-14
        • 2023-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-13
        • 2011-04-08
        相关资源
        最近更新 更多