C ++中的“深层复制”构造函数

问题描述 投票:-2回答:3

我想构建一个副本构造器Pair(const Pair& other)。这以对另一个Pair的只读引用为参数。它应将新构建的Pair设置为“深层副本”。但是我不知道如何在这些新位置设置整数,应该根据其他Pair指向的整数为其分配值。

class Pair {
public:
  int *pa,*pb;
  Pair(int a, int b);
  Pair(const Pair & other);
  ~Pair();
};

Pair::Pair(int a, int b){
  pa = new int;
  pb = new int;
  *pa = a;
  *pb = b;
}

Pair::Pair(const Pair & other){
  pa = new int;
  pb = new int;
  *pa = *(other.pa);
  *pb = *(other.pb);
}

Pair::~Pair(){
  delete pa;
  delete pb;
}

int main() {
  Pair p(15,16);
  Pair q(p);
  Pair *hp = new Pair(23,42);
  delete hp;

  std::cout << "If this message is printed,"
    << " at least the program hasn't crashed yet!\n"
    << "But you may want to print other diagnostic messages too." << std::endl;
  return 0;
}
c++ pointers constructor copy-constructor deep-copy
3个回答
2
投票

您的转换构造函数没有为其分配的int分配值,也没有为这些类成员分配这些指针。

Your copy构造函数同样没有将分配的指针分配给类成员。访问*的成员时,它也没有正确使用other运算符。

您的析构函数需要delete构造函数分配的类成员。

并且您需要添加复制分配运算符以正确完成Rule of 3

尝试一下:

class Pair {
public:
  int *pa,*pb;
  Pair(int a, int b);
  Pair(const Pair & other);
  ~Pair();
  Pair& operator=(const Pair & other);
};

Pair::Pair(int a, int b){
  pa = new int;
  pb = new int;
  *pa = a;
  *pb = b;

  /* alternatively:
  pa = new int(a);
  pb = new int(b);
  */
}

Pair::Pair(const Pair & other){
  pa = new int;
  pb = new int;
  *pa = *(other.pa);
  *pb = *(other.pb);

  /* alternatively:
  pa = new int(*(other.pa));
  pb = new int(*(other.pb));
  */
}

Pair::~Pair(){
  delete pa;
  delete pb;
}

Pair& Pair::operator=(const Pair & other){
  if (&other != this){
    Pair copy(other);
    int *temp;

    temp = copy.pa;
    copy.pa = pa;
    pa = temp;

    temp = copy.pb;
    copy.pb = pb;
    pb = temp;

    /* alternatively:
    std::swap(pa, copy.pa);
    std::swap(pb, copy.pb);
    */
  }

  return *this;
}

int main() {
  Pair p(15,16);
  Pair q(p);
  Pair *hp = new Pair(23,42);
  p = *hp;
  delete hp;

  std::cout << "If this message is printed,"
    << " at least the program hasn't crashed yet!\n"
    << "But you may want to print other diagnostic messages too." << std::endl;
  return 0;
}

1
投票

您的第一个构造函数可能看起来像这样:

Pair::Pair(int a, int b)
    : pa(new int(a))
    , pb(new int(b))
{
}

而且您无需通过转发到第一个构造函数来多次编写复杂的代码。

Pair::Pair(const Pair & other) 
    : Pair(*other.pa, *other.pb) 
{
}

另一件事是,您还必须实现赋值运算符。否则,如果您不小心进行赋值,您的代码将很容易出错(因为假设析构函数已正确实现,您将获得双倍delete。]

话虽如此,您的析构函数应该是:

Pair::~Pair()
{
    delete pa;
    delete pb;
}

正如其他人所说,直接为成员使用int会更简单,因为您不必自己定义复制和分配。

// Inside class declaration
Pair &operator=(const Pair &other);

// With other definitions.
Pair &Pair::operator=(const Pair &other)
{
    *pa = other.pa;
    *pb = other.pb;
    return *this;
}

如果您确实需要指针,那么我建议您改用std::unique_ptr

在您的课堂上,声明变成std::unique_ptr<int> pa;,而对于pb则类似。届时,您的析构函数将变为空。其余代码可以保持不变。

此外,最好避免使变量成员为public,在这种情况下,甚至在动态分配内存的情况下,甚至更多。


-2
投票

您的init构造函数和copy构造函数可能有一些错误。在我看来:初始化构造函数应为:

© www.soinside.com 2019 - 2024. All rights reserved.