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

发布于 2024-08-29 09:04:07 字数 165 浏览 9 评论 0原文

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

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

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

Are there some drawbacks of such implementation of copy-constructor?

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

As I remember, it was recommend in some book to call copy constructor from assignment operator and use well-known swap trick, but I don't remember, why...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

赏烟花じ飞满天 2024-09-05 09:04:07

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

交换技巧是这样的:

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 

Yes, that's a bad idea. All member variables of user-defined types will be initialized first, and then immediately overwritten.

That swap trick is this:

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 
溇涏 2024-09-05 09:04:07

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

缺点:

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

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

收益:

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

There are both potential drawbacks and potential gains from calling operator=() in your constructor.

Drawbacks:

  • Your constructor will initialize all the member variables whether you specify values or not, and then operator= will initialize them again. This increases execution complexity. You will need to make smart decisions about when this will create unacceptable behavior in your code.

  • Your constructor and operator= become tightly coupled. Everything you need to do when instantiating your object will also be done when copying your object. Again, you have to be smart about determining if this is a problem.

Gains:

  • The codebase becomes less complex and easier to maintain. Once again, be smart about evaluating this gain. If you have a struct with 2 string members, it's probably not worth it. On the other hand if you have a class with 50 data members (you probably shouldn't but that's a story for another post) or data members that have a complex relationship to one another, there could be a lot of benefit by having just one init function instead of two or more.
醉酒的小男人 2024-09-05 09:04:07

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

  • 复制函数应确保复制对象的所有数据成员及其所有基类部分。
  • 不要尝试根据其中一个复制功能来实现另一个复制功能。相反,将通用功能放在第三个函数中,
    打电话。

You're looking for Scott Meyers' Effective C++, Item 12: "Copy all parts of an object", whose summary states:

  • Copying functions should be sure to copy all of an object's data members and all of its base class parts.
  • Don't try to implement one of the copying functions in terms of the other. Instead, put common functionality in a third function that both
    call.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文