根据operator=实现复制构造函数
如果 operator=
定义正确,是否可以使用以下内容作为复制构造函数?
MyClass::MyClass(MyClass const &_copy)
{
*this = _copy;
}
If the operator=
is properly defined, is it OK to use the following as copy constructor?
MyClass::MyClass(MyClass const &_copy)
{
*this = _copy;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
是的。
就我个人而言,如果你的类没有指针,尽管我不会重载等于运算符或编写复制构造函数并让编译器为你做这件事;它将实现浅复制,您将确定所有成员数据都被复制,而如果您重载 = op;然后添加一个数据成员,然后忘记更新重载,你就会遇到问题。
yes.
personally, if your class doesn't have pointers though I'd not overload the equal operator or write the copy constructor and let the compiler do it for you; it will implement a shallow copy and you'll know for sure that all member data is copied, whereas if you overload the = op; and then add a data member and then forget to update the overload you'll have a problem.
@Alexandre - 我不确定在赋值运算符中按值传递。在那里调用复制构造函数有什么好处?这会紧固赋值运算符吗?
PS我不知道怎么写评论。或者可能是我不被允许写评论。
@Alexandre - I am not sure about passing by value in assignment operator. What is the advantage you will get by calling copy constructor there? Is this going to fasten the assignment operator?
P.S. I don't know how to write comments. Or may be I am not allowed to write comments.
如果您有一个有效的赋值运算符(复制运算符),那么从技术上讲,这是可以的。
但是,您应该更喜欢复制和交换,因为:
It is technically OK, if you have a working assignment operator (copy operator).
However, you should prefer copy-and-swap because:
如果
MyClass
的所有成员都有默认构造函数,那么是的。请注意,通常情况是相反的:
我们在
operator=
中传递值,以便调用复制构造函数。请注意,一切都是异常安全的,因为swap
保证不会抛出(您必须在实现中确保这一点)。根据要求编辑关于按值调用的内容:
operator=
可以这样编写,因为C++ 学生通常被告知通过引用传递类实例,因为如果通过传递类实例,则复制构造函数会被调用价值。在我们的例子中,无论如何我们都必须复制 rhs,所以按值传递是可以的。
因此,operator=(第一个版本,按值调用)读取:
rhs
的副本(通过复制构造函数,自动调用)交换*this
*this
并让rhs
(包含旧值)在方法退出时被销毁。现在,我们通过这种按值调用获得了额外的好处。如果传递给
operator=
的对象(或任何通过值获取其参数的函数)是一个临时对象,编译器可以(并且通常)在以下位置不进行复制:全部。这称为复制省略。因此,如果
rhs
是临时的,则不会进行任何复制。我们剩下:this
和rhs
内容rhs
因此,在这种情况下,按值传递更高效而不是通过引用传递。
If all members of
MyClass
have a default constructor, yes.Note that usually it is the other way around:
We pass by value in
operator=
so that the copy constructor gets called. Note that everything is exception safe, sinceswap
is guaranteed not to throw (you have to ensure this in your implementation).EDIT, as requested, about the call-by-value stuff: The
operator=
could be written asC++ students are usually told to pass class instances by reference because the copy constructor gets called if they are passed by value. In our case, we have to copy
rhs
anyway, so passing by value is fine.Thus, the
operator=
(first version, call by value) reads:rhs
(via the copy constructor, automatically called)*this
*this
and letrhs
(which contains the old value) be destroyed at method exit.Now, we have an extra bonus with this call-by-value. If the object being passed to
operator=
(or any function which gets its arguments by value) is a temporary object, the compiler can (and usually does) make no copy at all. This is called copy elision.Therefore, if
rhs
is temporary, no copy is made. We are left with:this
andrhs
contentsrhs
So passing by value is in this case more efficient than passing by reference.
更建议根据异常安全复制构造函数来实现operator=。请参阅 Herb Sutter 的示例 4,了解该技术的解释以及为什么这是一个好主意。
http://www.gotw.ca/gotw/059.htm
It is more advisable to implement operator= in terms of an exception safe copy constructor. See Example 4. in this from Herb Sutter for an explanation of the technique and why it's a good idea.
http://www.gotw.ca/gotw/059.htm
此实现意味着所有数据成员(和基类)的默认构造函数都可以从 MyClass 中使用和访问,因为在进行赋值之前将首先调用它们。即使在这种情况下,对构造函数的额外调用也可能会很昂贵(取决于类的内容)。
我仍然会坚持通过初始化列表单独实现复制构造函数,即使这意味着编写更多代码。
另一件事:此实现可能会产生副作用(例如,如果您有动态分配的成员)。
This implementation implies that the default constructors for all the data members (and base classes) are available and accessible from MyClass, because they will be called first, before making the assignment. Even in this case, having this extra call for the constructors might be expensive (depending on the content of the class).
I would still stick to separate implementation of the copy constructor through initialization list, even if it means writing more code.
Another thing: This implementation might have side effects (e.g. if you have dynamically allocated members).
虽然最终结果是相同的,但成员首先被默认初始化,然后才被复制。
对于“昂贵”的成员,您最好使用初始值设定项列表进行复制构造。
While the end result is the same, the members are first default initialized, only copied after that.
With 'expensive' members, you better copy-construct with an initializer list.
我想说如果
MyClass
分配内存或者是可变的,这是不行的。I would say this is not okay if
MyClass
allocates memory or is mutable.