【问题标题】:How to implement overloading of assignment operators in C++?如何在 C++ 中实现赋值运算符的重载?
【发布时间】:2017-11-30 18:07:29
【问题描述】:

我正在尝试使用赋值运算符重载来执行深层复制,但无法找到正确的方法。我有一台计算机类,需要使用它将其对象复制到笔记本电脑类的对象。

【问题讨论】:

  • 我们将不胜感激您想要做什么的代码示例。

标签: oop c++11 operator-overloading


【解决方案1】:

它应该看起来像这样:

#include <algorithm>

class SomeClass {};
class AnotherClass {};

class Computer
{
 public:
  Computer() :
   m_someclass(new SomeClass()),
   m_double(0.0)
  {
  }

  virtual ~Computer()
  {
    delete m_someclass;
  }

  Computer(const Computer& other) :
   m_someclass(new SomeClass(*other.m_someclass)),
   m_double(other.m_double)
  {
  }

  Computer& operator=(const Computer& other)
  {
    if (this != &other)
    {
      Computer tmp(other);
      swap(tmp);
    }
    return *this;
  }

  void swap(Computer& other) noexcept // or throw() for before c++11
  {
    std::swap(m_someclass, other.m_someclass);
    std::swap(m_double, other.m_double);
  }

 private:
  SomeClass* m_someclass;
  double m_double;
};

class Laptop : public Computer
{
 public:
  Laptop() :
   m_anotherclass(new AnotherClass()),
   m_int(0)
  {
  }

  virtual ~Laptop()
  {
    delete m_anotherclass;
  }

  Laptop(const Laptop& other) :
   Computer(other),
   m_anotherclass(new AnotherClass(*other.m_anotherclass)),
   m_int(other.m_int)
  {
  }

  // Create a Laptop object from a Computer object
  explicit Laptop(const Computer& other) :
   Computer(other),
   m_anotherclass(new AnotherClass()),
   m_int(0)
  {
  }

  Laptop& operator=(const Laptop& other)
  {
    if (this != &other)
    {
      Laptop tmp(other);
      swap(tmp);
    }
    return *this;
  }

  // Assign a laptop object from a computer object.
  Laptop& operator=(const Computer& other)
  {
    if (this != &other)
    {
      Laptop tmp(other);
      swap(tmp);
    }
    return *this;
  }

  void swap(Laptop& other) noexcept // or throw() for before c++11
  {
    Computer::swap(other);
    std::swap(m_anotherclass, other.m_anotherclass);
    std::swap(m_int, other.m_int);
  }

 private:
  AnotherClass* m_anotherclass;
  int m_int;
};

int main()
{
  Computer computer;

  // Construct a new Laptop object by copying data from a Computer object
  Laptop laptop1(computer);

  // Assign Computer data in Laptop to that of a Computer object
  Laptop laptop2;
  laptop2 = computer;
}

对于非指针成员变量,您只需使用 operator= 执行标准复制。对于指针成员变量(对象拥有),您使用 new 运算符并使用另一个对象拥有的指针构造它。

【讨论】:

  • 通常你必须在设置新资源之前释放你的旧资源。所以你需要检查if ( m_someclass &amp;&amp; m_someclass != other.m_someclass ) delete m_someclass;覆盖m_someclass。仅当 other.m_someclass != nullptr 时才调用复制构造函数。
  • 啊,很好的点。虽然,我认为您不需要在删除 if (m_someclass) 之前检查它,因为删除空指针是安全的。此外,如果每个对象“拥有”它的 m_someclass,那么我认为两个不同的对象不会有相同的 m_someclass。但我还是把支票放在那里。为了异常安全,我还在临时指针上使用了new SomeClass - 如果新抛出,m_someclass 将保持不变。让我知道你的想法。
  • 权利和权利,如果所有权是明确的。它仍然不是非常安全的。通常,您需要拆分抛出的代码并在开始时执行此操作,并将成员变量设置在不抛出的第二部分中。现在你可以进入 m_double si 被覆盖但 m_someclass 没有被覆盖的情况。您可以将其向下移动或使用 temp var。还可以修复您的班级以规避“三规则”
  • 我同意智能指针。我现在几乎总是使用它们。但是 OP 并没有详细说明他的类中的指针类型,所以我只使用了传统的 raw。
  • 我将 m_double 分配移动到复制分配的第二部分。我还添加了构造函数和复制构造函数,使其遵守“三规则”。
猜你喜欢
  • 1970-01-01
  • 2012-08-17
  • 2013-03-30
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 2012-04-22
  • 2015-06-01
  • 2011-01-27
相关资源
最近更新 更多