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

ovfsdjhp  于 2023-03-09  发布在  其他
关注(0)|答案(5)|浏览(149)

我想构建一个复制构造函数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;
}
zsbz8rwp

zsbz8rwp1#

你的第一个构造函数可能如下所示:

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,在动态分配内存的情况下,甚至更多。

daupos2t

daupos2t2#

您的 converting 构造函数没有将值赋给它分配的int,也没有将那些指针赋给类成员。
你的 copy 构造函数同样没有将分配的指针赋给类成员,在访问other的成员时也没有正确使用*操作符。
你的 * 析构函数 * 需要delete构造函数分配的类成员。
您需要添加一个 *copy赋值操作符 * 来正确地完成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){
  *pa = *(other.pa);
  *pb = *(other.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;
}
xzabzqsa

xzabzqsa3#

可以使用自定义构造函数、复制构造函数,如下所示:

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

 /*
 * Implement its member functions below.
 */
 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;
}

 /* Here is a main() function you can use
  * to check your implementation of the
  * class Pair member functions.
  */

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;
}
vawmfj5a

vawmfj5a4#

类对{ public:整数 *pa,*pb ;对(整数,整数);对(常数对&);~配对(); };
Pair::Pair(整数a,整数B){ pa =新的整数(a);pb =新整数(b);}
对::对(常数对&p){对 *pr=新对(*p.pa,*p.pb);pa = pr -〉pa;Pb = Pr -〉Pb;}对::~对(){删除页,pb;}
int main(){对p(15,16);对q(p);对 *hp =新对(23,42);删除hp;
std::cout〈〈“如果打印此消息,”〈〈“至少程序还没有崩溃!\n”〈〈“但您可能还想打印其他诊断消息。”〈〈std::endl;返回0; }

jq6vz3qz

jq6vz3qz5#

您的init构造函数和复制构造函数可能有一些错误。
init构造函数应为:

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);
}

相关问题