質問

私は class A を使用するヒープメモリ割り当てのための一つ。ラスのインスタンスが作成して保存したポインタの分野別のクラスclass B.

私は、オブジェクトのクラスB、私 delete, るいはデストラクタ...ではこの呼び出しのデストラクタのクラスでも見ることができますか?

編集:

からの回答をしていること(編集が間違った):

  1. delete のインスタンスのマー B::~B();
  2. を呼びかけ A::~A();
  3. A::~A すべ 明示的に delete すべてのヒープの割り当てのメンバ変数は、オブジェクト
  4. 最後に、メモリブロックの保管とのインスタンスBクラスが返されるエディタで開き、ヒープが 新しい 使用したので、最初に割り当てるメモリブロックヒープを呼び出しのコンストラクタを初期化する方法についても、今後すべてのdestructors呼び出されたものを完了させるためのオブジェクトのブロックのオブジェクトに滞在が返されるヒープ.
役に立ちましたか?

解決

その寿命が終わったとき、Aのデストラクタが実行されます。あなたはそのメモリが解放され、デストラクタの実行させたい場合は、それがヒープに割り当てられた場合、それを削除する必要があります。それはスタック上に割り当てられた場合(これはスコープの外に出たとき、すなわち、RAIIを参照)、これは自動的に行われます。それはクラスのメンバ(ないポインタが、完全なメンバー)である場合を含むオブジェクトが破棄されるとき、これは起こる。

class A
{
    char *someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { delete[] someHeapMemory; }
};

class B
{
    A* APtr;
public:
    B() : APtr(new A()) {}
    ~B() { delete APtr; }
};

class C
{
    A Amember;
public:
    C() : Amember() {}
    ~C() {} // A is freed / destructed automatically.
};

int main()
{
    B* BPtr = new B();
    delete BPtr; // Calls ~B() which calls ~A() 
    C *CPtr = new C();
    delete CPtr;
    B b;
    C c;
} // b and c are freed/destructed automatically

上記の例では、すべての[]は必要とされているを削除し、削除します。そして、何の削除は(実際に使用することができたり)私はそれを使用していないところ必要ありません。

auto_ptrunique_ptrshared_ptr等...この寿命管理がはるかに簡単に作るための素晴らしいです。

class A
{
    shared_array<char> someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { } // someHeapMemory is delete[]d automatically
};

class B
{
    shared_ptr<A> APtr;
public:
    B() : APtr(new A()) {}
    ~B() {  } // APtr is deleted automatically
};

int main()
{
    shared_ptr<B> BPtr = new B();
} // BPtr is deleted automatically

他のヒント

あなたは新しいによって割り当てられたポインタに削除を呼び出すと、オブジェクトのデストラクタが呼び出されますし指さます。

A * p = new A;

delete p;    // A:~A() called for you on obkect pointed to by p

これは、 "デストラクタ" ではなく、 "デコンストラクタ" という名前が付けられます。

各クラスのデストラクタの中に、あなたは新しいして割り当てられている他のすべてのメンバ変数を削除する必要があります。

編集:明確にします:

あなたが持っていると言います
struct A {}

class B {
    A *a;
public:
    B () : a (new A) {}
    ~B() { delete a; }
};

class C {
    A *a;
public:
    C () : a (new A) {}        
};

int main () {
    delete new B;
    delete new C;
}
何Bは内部もデストラクタで削除されますので、割り当て

Bのインスタンスを割り当てた後、削除は、クリーンでます。

しかし、それは(この場合、Cもデストラクタを持たない)を解放しないのインスタンスを割り当てるため、クラスCのインスタンスは、メモリリークが発生します。

あなたはいつものポインタ(A*)を持っている場合は、デストラクタが呼び出されません(とAインスタンスのメモリがどちらか解放されません)あなたはdeleteのデストラクタで明示的にBない場合を除きます。あなたはauto_ptrのようなスマートポインタの自動破壊の外観をしたい場合。

あなたはBのデストラクタで自分自身を削除する必要があります。

class B
{
public:
    B()
    {
       p = new int[1024];  
    }
    virtual ~B()
    {
        cout<<"B destructor"<<endl;
        //p will not be deleted EVER unless you do it manually.
    }
    int *p;
};


class D : public B
{
public:
    virtual ~D()
    {
        cout<<"D destructor"<<endl;
    }
};

あなたが行うとます:

B *pD = new D();
delete pD;

デストラクタがあなたの基底クラスが仮想キーワードを持っている場合にのみ呼び出されます。

次に、あなただけの〜B()が呼び出されることになる仮想デストラクタを持っていなかった場合。あなたは仮想デストラクタを持っているのでしかし、最初の〜D()が呼び出されます、そして、〜B()。

あなたが明示的に削除しない限り、

ヒープに割り当てBまたはDのいかなるメンバーが割り当て解除されません。そして、それらを削除すると、同様に彼らのデストラクタを呼び出します。

私のクラスのデストラクタが呼び出されなかった理由を

私は思っていました。その理由は、私は、そのクラス(の#include「class.h」)の定義を含めるのを忘れていたことでした。私だけのような宣言が持っていた「クラスAを;」コンパイラはそれで幸せだったと私は、「削除」を呼び出してみましょう。

はありません。ポインタが削除されます。あなたはBのデストラクタで明示的に削除を呼び出す必要があります。

削除は、そのオブジェクトに対して呼び出された場合は、

クラスAのオブジェクトのデストラクタは呼び出されます。クラスBのデストラクタでそのポインタを削除することを確認します。

オブジェクトで呼び出されたときに、削除何が起こるかについて少し詳細については、以下を参照してください。 http://www.parashift.com/c++-よくある質問-LITE / freestore-mgmt.html#FAQ-16.9

いいえ、それは「PTR削除;」行を削除し、(PoweRoyが語ったように)あなたが明示的に呼び出す必要があり、クラスAのためのデストラクタを呼び出すことはありません例に比較する...

  #include <iostream>

  class A
  {
     public:
        A(){};
        ~A();
  };

  A::~A()
  {
     std::cout << "Destructor of A" << std::endl;
  }

  class B
  {
     public:
        B(){ptr = new A();};
        ~B();
     private:
        A* ptr;
  };

  B::~B()
  {
     delete ptr;
     std::cout << "Destructor of B" << std::endl;
  }

  int main()
  {
     B* b = new B();
     delete b;
     return 0;
  }

は、

のようなものを持っています
class B
{
   A * a;
}
B * b = new B;
b->a = new A;
あなたがdelete b;を呼び出す場合は、

、何も起こりませんし、あなたがメモリリークを持っています。 delete b->a;に思い出そうとするのは得策ではありませんが、他のカップルがあります。

B::~B() {delete a;}

これは、削除させていただきますBのデストラクタです。 (0であれば、それは削除何もしません。0ではありませんが、新しいからメモリを指していない場合は、ヒープの破損を取得します。)

auto_ptr<A> a;
...
b->a.reset(new A);
bがあるときに

この方法は、あなたはポインタとして持っていないが、むしろ、auto_ptrは<>(shared_ptrの<>だけでなく、または他のスマートポインタを行います)、それが自動的に削除されます。

これらのいずれかの方法でうまく機能し、私は両方を使用しました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top