关于c ++:在复制构造函数中调用赋值运算符

Calling assignment operator in copy constructor

这种复制构造函数的实现有什么缺点吗?

1
2
3
4
Foo::Foo(const Foo& i_foo)
{
   *this = i_foo;
}

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


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

交换技巧是:

1
2
3
4
5
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


在构造函数中调用operator=()既有潜在的缺点,也有潜在的收益。

缺点:

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

  • 您的构造函数和operator=将紧密耦合。实例化对象时需要做的所有事情也将在复制对象时完成。同样,你必须聪明地确定这是否是一个问题。

利润:

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


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