簡體   English   中英

如何在C ++中進行深層復制

[英]How do I do a deep copy in c++

我正在嘗試對類B進行深層復制,但是A沒有設置。

為什么b3->print返回一個垃圾數字而不是1

據我了解,b2和b3都指向同一個A對象。 但是我使用B的復制構造函數在堆上創建了一個新對象。 那么為什么他們倆都還在同一個對象下垂呢?

我希望這是有道理的。

#include <cstdlib>
#include <iostream>

using namespace std;

class A{
      int num;
public:
       A(int n):num(n){ cout<< "A "<< num << " constructor" <<endl;}  
       ~A(){ cout<< "A "<< num <<" destructor. " <<endl; }   

       int print(){
        cout<< num<< endl;
       }
};

class B{
      A *a;
      int num;
public:
       B(int n):num(n){
           a = new A(n);
           cout<< "B "<< num <<" constructor" <<endl;    
       }  
       ~B(){
            delete a; 
            cout<< "B "<< num <<" destructor"<<endl; 
       }    
       // Copy contructor
       B(const B & b): a(new A(b.num)){ 
       } 

       <strike>int<\strike> void print(){
        cout<< num << endl;
       }

       int get_num(){
           return num;
       }
};

int main(int argc, char *argv[])
{ 
    B *b2 = new B(1);
    B *b3(b2);
    b2->print();
    delete b2;
    b3->print();
    system("PAUSE");
    return EXIT_SUCCESS;
}

B *b3(b2); 不按照你的想法做。

等效於B* b3 = b2 指針將指向相同的位置。 當您delete b2; ,您還可以釋放b3指向的內存。

要進行深度復制,請執行以下操作:

 B* b3 = new B(*b2);

這里也有未定義的行為:

int print(){
   cout<< num << endl;
}

因為你永遠不會回來。 將返回類型更改為void

要獲得期望的值:

B(const B & b): a(new A(b.num)), num(b.num){ 
} 

該問題的其他答案將說明有關指針如何工作的,但您還應該了解,不使用指針是更好的解決方案。 C ++的默認行為可以很好地與值語義配合使用。 如果按值保存對象,則默認的復制ctor和賦值運算符將執行“深層復制”。

class B{
    A a;
    int num;
public:
    B(int n): a(n), num(n){
        cout<< "B "<< num <<" constructor" <<endl;    
    }    

    void print(){
        cout<< num << endl;
    }

    int get_num(){
        return num;
    }
};

另外,如果您確實使用擁有指針,則通常應使用智能指針。

我想您可能打算寫這樣的東西:

#include <iostream>

class A
{
public:
    A(int n) : num_(n) {}

    void print() { std::cout << num() << std::endl; }

    int num() const { return num_; }

private:
    int num_;
};

class B
{
public:
    B(int n) : a(n) {}

    int num() const { return a.num(); }

private:
    A a;
};

int main()
{
    B b(1);
    B b2 = b; // deep copy
}

如你看到的:

  1. B沒有自己的num_成員。 應避免重復。
  2. 無需實現復制構造函數或賦值運算符(3條規則)。
  3. 不需要在這里使用new

在這里,您不復制b2

B *b3(b2);

相反,您使b3指向b2

你應該有

B *b3 = new B(*b2);

在c ++中,沒有淺/深復制這樣的東西。 您要么具有要復制的值,要么具有指針/引用,它們完全定義了復制操作的語義。

暫無
暫無

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

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