Oop 如何在C++;?

Oop 如何在C++;?,oop,c++11,operator-overloading,Oop,C++11,Operator Overloading,我试图使用赋值运算符重载来执行深度复制,但无法找到正确的方法。我有一台Class计算机,需要使用它将其对象复制到Class Laptop的对象。它应该是这样的: #include <algorithm> class SomeClass {}; class AnotherClass {}; class Computer { public: Computer() : m_someclass(new SomeClass()), m_double(0.0) {

我试图使用赋值运算符重载来执行深度复制,但无法找到正确的方法。我有一台Class计算机,需要使用它将其对象复制到Class Laptop的对象。

它应该是这样的:

#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;
}
#包括
类SomeClass{};
另一类{};
班级电脑
{
公众:
计算机():
m_someclass(新的someclass()),
m_double(0.0)
{
}
虚拟计算机
{
删除m_someclass;
}
计算机(常数计算机和其他):
m_someclass(new someclass(*other.m_someclass)),
m_double(其他。m_double)
{
}
计算机和操作员=(常量计算机和其他)
{
如果(此!=&其他)
{
计算机tmp(其他);
掉期(tmp);
}
归还*这个;
}
c++11之前版本的void swap(计算机和其他)noexcept//或throw()
{
std::swap(m_someclass,other.m_someclass);
std::swap(mu-double,其他.mu-double);
}
私人:
SomeClass*m_SomeClass;
双m_双;
};
类别手提电脑:公共电脑
{
公众:
笔记本电脑():
m_另一个类(新的另一个类()),
m_int(0)
{
}
虚拟笔记本电脑()
{
删除另一个类;
}
笔记本电脑(常数笔记本电脑和其他):
计算机(其他),
m_anotherclass(新的anotherclass(*other.m_anotherclass)),
m_int(其他.m_int)
{
}
//从计算机对象创建笔记本电脑对象
显式笔记本电脑(常数计算机和其他):
计算机(其他),
m_另一个类(新的另一个类()),
m_int(0)
{
}
笔记本电脑和操作员=(常数笔记本电脑和其他)
{
如果(此!=&其他)
{
笔记本电脑tmp(其他);
掉期(tmp);
}
归还*这个;
}
//从计算机对象指定笔记本电脑对象。
笔记本电脑和操作员=(常数计算机和其他)
{
如果(此!=&其他)
{
笔记本电脑tmp(其他);
掉期(tmp);
}
归还*这个;
}
c++11之前版本的void swap(笔记本电脑和其他)noexcept//或throw()
{
计算机:交换(其他);
std::swap(m_其他类,other.m_其他类);
std::swap(m_int,other.m_int);
}
私人:
另一类*m_另一类;
int m_int;
};
int main()
{
计算机;
//通过从计算机对象复制数据来构造新的膝上型计算机对象
笔记本电脑laptop1(电脑);
//将笔记本电脑中的计算机数据分配给计算机对象的数据
笔记本电脑laptop2;
laptop2=计算机;
}

对于非指针成员变量,只需使用运算符=。对于指针成员变量(对象所拥有的),您可以使用新运算符并使用另一个对象所拥有的指针来构造它。

通常,在设置新值之前,您必须释放旧资源。因此,您需要检查
是否(m_someclass&&m_someclass!=other.m_someclass)删除m_someclass覆盖m_someclass。仅当other.m_someclass!=nullptr。啊,非常好的观点。尽管如此,我认为在删除它之前不需要检查
if(m_someclass)
,因为删除空指针是安全的。此外,如果每个对象“拥有”其m_someclass,那么我认为两个不同的对象不会拥有相同的m_someclass。但我还是把支票放在那里了。我还在临时指针上使用了
newsomeclass
,以确保异常安全-如果new抛出,m_SomeClass将保持不变。让我知道你的想法。如果所有权明确的话,再正确不过了。它仍然不太安全。通常,您需要将抛出的代码拆分并在开始时执行,然后在不抛出的第二部分中设置成员变量。现在您可以进入这样一种情况,即m_double si被覆盖,但m_someclass未被覆盖。您可以将其向下移动或使用temp变量。还可以根据“三个规则”修复您的类,我同意智能指针。我现在几乎总是用它们。但是OP没有给出他类中指针类型的详细信息,所以我只使用传统的raw。我将m_双赋值移到了第二部分,用于复制赋值。我还添加了一个构造函数和一个复制构造函数,这样它就遵守了“三个规则”。如果您能提供一个代码示例,说明您到底想做什么,我们将不胜感激。