简体   繁体   English

如果我用非const参数定义那些,我仍然可以得到默认的复制构造函数和operator =吗?

[英]Do I still get default copy constructor and operator= if I define ones with non-const arguments?

In C++, if I define a copy constructor and operator= that take a non-const reference to the class, is the compiler supposed to still supply default versions for const reference? 在C ++中,如果我定义了一个复制构造函数和operator =对该类采用非const引用,那么编译器是否应该仍然为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);
};

No, if you define a copy constructor and assignment operator, the compiler will not implicitly declare or define it's own. 不,如果您定义了复制构造函数和赋值运算符,编译器将不会隐式声明或定义它自己的。 Note that the definition of copy-constructor allows for the argument to be taken by either const or non-const reference, so your constructor is indeed a copy-constructor . 请注意, copy-constructor的定义允许参数由const或非const引用获取,因此构造函数确实是一个复制构造函数 Similarly for operator= 同样适用于operator=

[ Omitting a big part of the details, in particular under what circumstances the implicitly declared special member functions will also be implicitly defined] [ 省略大部分细节,特别是在什么情况下隐式声明的特殊成员函数也将被隐式定义]

12.8 [class.copy]/2 A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6). 12.8 [class.copy] / 2如果X类的第一个参数是X&,const X&,volatile X&或const volatile X&,并且没有其他参数或者其他所参数有默认参数(8.3.6)。

12.8 [class.copy]/7 If the class definition does not explicitly declare a copy constructor, one is declared implicitly. 12.8 [class.copy] / 7如果类定义没有显式声明复制构造函数,则会隐式声明一个。

12.8 [class.copy]/17 A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&. 12.8 [class.copy] / 17用户声明的复制赋值运算符X :: operator =是类X的非静态非模板成员函数,只有一个参数类型为X,X&,const X&,volatile X&或const易变的X&。

12.8 [class.copy]/18 If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. 12.8 [class.copy] / 18如果类定义没有显式声明一个复制赋值运算符,则会隐式声明一个。

No, once you declare your own copy constructor or copy assignment operator (whether or not it uses the canonical const ness) the compiler won't do it for you anymore. 不,一旦你声明自己的复制构造函数或复制赋值运算符(无论它是否使用规范const ),编译器将不再为你做这件事。

But doing this by non-const reference is pretty much a textbook example of violating the principle of least surprise. 但是通过非const引用来做这件事几乎是违反最小惊喜原则的教科书范例。 Everyone expects that const objects can be assigned from and that the right hand side won't be mutated. 每个人都希望可以从中分配const对象,并且右侧不会发生变异。 The first isn't so bad as the compiler will catch it but the second could cause a variety of hard-to-spot bugs. 第一个并不是很糟糕,因为编译器会捕获它,但第二个可能导致各种难以发现的错误。

If you're trying to implement move semantics and you can't use C++11, I would suggest creating a special move method and just not allowing "move" construction at all. 如果你试图实现移动语义而你不能使用C ++ 11,我会建议创建一个特殊的移动方法,而根本不允许“移动”构造。 If you can use C++11 then use the builtin rvalue references. 如果您可以使用C ++ 11,那么使用内置右值引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM