[英]Implementing the copy constructor in terms of operator=
如果正确定义了operator=
,可以使用以下作为复制构造函数吗?
MyClass::MyClass(MyClass const &_copy)
{
*this = _copy;
}
如果MyClass
所有成员都有默认构造函数,那么是。
请注意,通常它是相反的方式:
class MyClass
{
public:
MyClass(MyClass const&); // Implemented
void swap(MyClass&) throw(); // Implemented
MyClass& operator=(MyClass rhs) { rhs.swap(*this); return *this; }
};
我们在operator=
传递值,以便调用复制构造函数。 请注意,一切都是异常安全的,因为保证swap
不会抛出(您必须在实现中确保这一点)。
按要求编辑有关按值调用的内容: operator=
可写为
MyClass& MyClass::operator=(MyClass const& rhs)
{
MyClass tmp(rhs);
tmp.swap(*this);
return *this;
}
C ++学生通常被告知通过引用传递类实例,因为如果通过值传递复制构造函数,则会调用它。 在我们的例子中,我们必须复制rhs
,所以通过值传递是好的。
因此, operator=
(第一个版本,按值调用)读取:
rhs
的副本(通过复制构造函数,自动调用) *this
交换其内容 *this
并让方法退出时销毁rhs
(包含旧值)。 现在,我们通过这种按值调用获得额外奖励。 如果传递给operator=
的对象(或任何通过value获取其参数的函数)是一个临时对象 ,编译器可以(并且通常)根本不进行复制。 这称为复制省略 。
因此,如果rhs
是临时的,则不进行复制。 我们留下:
this
和rhs
内容 rhs
因此,在这种情况下,通过值传递比通过引用传递更有效。
根据异常安全拷贝构造函数,更可取的是实现operator =。 参见Herb Sutter的实施例4.对该技术的解释以及为什么这是一个好主意。
此实现意味着所有数据成员(和基类)的默认构造函数都可以从MyClass中访问和访问,因为在进行赋值之前将首先调用它们。 即使在这种情况下,对构造函数进行额外调用也可能很昂贵(取决于类的内容)。
我仍然坚持通过初始化列表单独实现复制构造函数,即使这意味着编写更多代码。
另一件事:此实现可能有副作用(例如,如果您有动态分配的成员)。
虽然最终结果是相同的,但成员首先默认初始化,之后才复制。
对于“昂贵”的成员,您最好使用初始化列表进行复制构造。
struct C {
ExpensiveType member;
C( const C& other ): member(other.member) {}
};
};
我会说如果MyClass
分配内存或者是可变的,这是不行的。
是。
就个人而言,如果你的类没有指针,虽然我不会重载相等的运算符或编写复制构造函数,让编译器为你做; 它将实现一个浅拷贝,你肯定会知道所有成员数据都被复制了,而如果你重载了= op; 然后添加一个数据成员,然后忘记更新您将遇到问题的重载。
@Alexandre - 我不确定在赋值运算符中传递值。 通过在那里调用复制构造函数可以获得什么优势? 这是否会固定赋值运算符?
PS我不知道怎么写评论。 或者可能是我不允许写评论。
这在技术上是好的,如果你有一个工作的赋值运算符(拷贝操作)。
但是,您应该更喜欢复制和交换,因为:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.