1

class のディープ コピーを実行しようとしています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;
}
4

5 に答える 5

14

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){ 
} 
于 2012-08-02T17:26:29.640 に答える
1

この質問に対する他の回答では、ポインターがどのように機能するかについて説明しますが、ポインターを使用しない方がより良い解決策であることも理解する必要があります。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;
    }
};

また、所有ポインターを使用する場合は、通常、スマート ポインターを使用する必要があります。

于 2012-08-02T17:46:36.677 に答える
0

おそらく次のようなことを書くつもりだったと思います。

#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
于 2012-08-02T17:29:40.780 に答える
0

ここではb2をコピーしていません

B *b3(b2);

代わりに、b3がb2を指すようにしています

あなたが持っている必要があります

B *b3 = new B(*b2);
于 2012-08-02T17:33:07.077 に答える
-7

C ++には浅い/深いコピーなどはありません。コピーされる値またはポインター/参照があり、コピー操作のセマンティクスを完全に定義します。

于 2012-08-02T17:32:05.930 に答える