在复制构造函数中调用赋值运算符

时间:2010-04-14 16:05:56

标签: c++ copy-constructor

复制构造函数的这种实现是否存在一些缺点?

Foo::Foo(const Foo& i_foo)
{
   *this = i_foo;
}

我记得,在某些书中建议从赋值运算符调用复制构造函数并使用众所周知的交换技巧,但我不记得了,为什么......

3 个答案:

答案 0 :(得分:20)

是的,这是一个坏主意。将首先初始化用户定义类型的所有成员变量,然后立即覆盖。

这个交换技巧是这样的:

Foo& operator=(Foo rhs) // note the copying
{
   rhs.swap(*this); //swap our internals with the copy of rhs
   return *this;
} // rhs, now containing our old internals, will be deleted 

答案 1 :(得分:8)

在构造函数中调用operator=()有两个潜在的缺点和潜在的好处。

缺点:

  • 无论您是否指定值,构造函数都会初始化所有成员变量,然后operator=将再次初始化它们。这增加了执行复杂性。您需要明智地决定何时会在您的代码中创建不可接受的行为。

  • 您的构造函数与operator=紧密耦合。复制对象时,还需要在实例化对象时执行的所有操作。同样,你必须聪明地确定这是否是一个问题。

收益:

  • 代码库变得不那么复杂,也更容易维护。再一次,要聪明地评估这个收益。如果你有一个包含2个字符串成员的结构,那么它可能不值得。另一方面,如果你有一个有50个数据成员的类(你可能不应该,但这是另一个帖子的故事)或者彼此之间有复杂关系的数据成员,那么只有一个可以有很多好处init函数而不是两个或更多。

答案 2 :(得分:3)

您正在寻找Scott Meyers' Effective C++第12项:复制对象的所有部分。