簡體   English   中英

C++ 中的“深拷貝”構造函數

[英]A 'deep copy' constructor in C++

我想構建一個復制構造函數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;
}

您的轉換構造函數沒有為其分配的int分配值,也沒有將這些指針分配給 class 成員。

您的復制構造函數同樣沒有將分配的指針分配給 class 成員。 訪問other成員時,它也沒有正確使用*運算符。

您的析構函數需要delete構造函數分配的 class 成員。

並且您需要添加一個復制賦值運算符才能正確完成規則 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;
}

您的第一個構造函數可能如下所示:

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

在您的 class 中,聲明變為std::unique_ptr<int> pa; pb類似。 那時你的析構函數變成空的。 其余代碼可以保持不變。

此外,最好避免將變量成員public ,甚至在動態分配 memory 的情況下避免公開變量成員。

您可以使用自定義構造函數,復制構造函數如下:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM