在复制构造函数中调用赋值运算符有缺点吗?

问题描述 投票:0回答:3

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

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

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

c++ copy-constructor assignment-operator
3个回答
23
投票

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

交换技巧是这样的:

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 

11
投票

在构造函数中调用

operator=()
既有潜在的缺点,也有潜在的好处。

缺点:

  • 无论您是否指定值,您的构造函数都会初始化所有成员变量,然后

    operator=
    将再次初始化它们。这增加了执行复杂性。您需要做出明智的决定,以确定何时这会在您的代码中产生不可接受的行为。

  • 你的构造函数和

    operator=
    变得紧密耦合。实例化对象时需要执行的所有操作也将在复制对象时完成。同样,您必须聪明地确定这是否是一个问题。

收获:

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

4
投票

您正在寻找 Scott Meyers 的《Effective C++》,第 12 条:“复制对象的所有部分”,其摘要指出:

  • 复制函数应确保复制对象的所有数据成员及其所有基类部分。
  • 不要尝试用其中一种复制功能来实现另一种复制功能。相反,将通用功能放在第三个函数中, 打电话。
© www.soinside.com 2019 - 2024. All rights reserved.