トップページ
ひらく | たたむ | ページトップ
↓マウスで反転選択した文字を検索
C++
   
ページ内検索 ページ外検索
検索したい文字を入力して
ENTERを押すと移動します。
\n
[ トップページ ]
[ ____CommandPrompt ] [ ____JScript ] [ ____MySQL ] [ ____Cygwin ] [ ____Java ] [ ____Emacs ] [ ____Make ] [ ____Perl ] [ ____Python ] [ ____OpenGL ] [ ____C# ] [ ____StyleSheet ] [ ____C++ ] [ ____Winsock ] [ ____Thread ] [ ____VisualStudio ] [ ____C ] [ ____Win32API ] [ ____Lua ] [ ____PhotoShop ]
ヘッダ検索

___

■ Destructor(デストラクタ)


  DESC
    デストラクタとはクラスのインスタンスが消滅する時点によばれるメソッド( 関数 )のこと
    普通はコンストラクタでした処理の後始末をする。

    コンストラクタは逆の順で実行される。
    ランタイムシステムが基底クラスのデストラクタもコールしてくれる。
    デストラクタ本体のコード --> メンバ変数のデストラクタ(宣言した変数の逆の順番) --> 基底クラスのデストラクタ
    class String {
      // コンストラクタで new をしたオブジェクトがあれば
      String() {
        m_data = new char[256];
      }

      // デストラクタで delete をする。
      ~String() {
        delete m_data;
      }
      
      
      char *m_data;
    };
コンストラクタと違い、1個しかもてない。
    class Test {
      ~Test();
    };
___

■ デストラクタのコールされるタイミング

デストラクタはオブジェクトが消滅する時にコールされる。 消滅するのは次のとき
     ローカルオブジェクトがブロックを抜けるとき。
     クラスのメンバオブジェクトは、そのクラスが消滅するときに一緒に
     一時オブジェクトはその式が終了したとき。
     動的に生成( new )されたオブジェクトは delete されるとき
___

■ デストラクタの自動生成

デストラクタを自分で定義しないとコンパイラが自動生成をする。 自動生成されるデストラクタは すべてのメンバのデストラクタを起動する。 コピーコンストラクタ も同様に定義しないとコンパイラが自動生成する。 REFERENCE CopyConstructor WARNING デストラクタを定義したら コピーコンストラクタも自前で定義をすること。 オブジェクトを参照するクラスの場合は多重に delete をすることになる。 つまりオブジェクトの所有権があいまいになるということ。
    {
      String s;

      // stmp::data は s::data と同じオブジェクトを指す
      {
        String stmp = s;
      }

      // s が消滅してデストラクタが起動すると data が2重に delete される。
    }  
POINT クラスがポインタをもち, リファレンス先を削除する義務がある( 所有者の )場合は コピーをする場合は オブジェクトを全体をコピーすること。( DeepCopy ) virtual にすると Instance の QUIT が call される. 明示的に delete を呼んだ場合, work の解放はされない /pro/test/virtualdtor/ POINT 派生クラスの Destructor が call されると 基底クラスの Destructor もコールされる Destructor が呼ばれるのは 2 とおりある System に call してもらう Stack Object delete 明示的に呼ぶ( 関数だから call しても問題なし ) d.~D();

class B2
{
 public:
  ~B2() { printf("B2::dtor dayo\n"); }
}; 
class D2 : public B2
{
 public:
  ~D2() { printf("D2::dtor\n"); }
}; 


void testDriveDtor()
{
  // 2 つ呼ばれる
  // D dtor
  // B dtor
  D d;

  // ~D() を呼べば 自動で 基底クラスの ~B() も呼ばれる
  d.~D();

  {
    //  ここも同じ
    D *d = new D();
    delete d;
  }
  
  // d はここで死ぬ
}

POINT delete bCls; とすると, bCls::dtor にアクセスすることになる. bCls が interface の場合は当然削除できない. WARNING virtual にしないと、その object の destructor しかコールされない
___

■ 仮想デストラクタ

仮想関数をもつクラスは基底クラスのデストラクタを仮想関数にする。 POINT より正確な条件は 基底クラスのポインタをつかって delete するならば、 そのクラスは 仮想デストラクタをもつ必要がある。
___

■ 仮想デストラクタ

この場合は Child のデストラクタが実行される。 Title のコンストラクタで実行した処理の解放処理がされない。
    Child *cld = new Title;
そこで デストラクタも仮想関数にしてあげる
    class Gui {

      virtual void draw();
      virtual ~Gui();       // 仮想デストラクタにする必要がある。
    };



    // 仮想関数のよびだしは 基底クラスのポインタ( 参照 )をつかってする。
    for each GuiList {
      gui->draw();  // virtual method
    }

    for each GuiList {
      delete gui;  // ここで各 GUI ( ボタン, スライダ, ウィンドウ )ごとのデストラクタが呼ばれる。
    }    
仮想デストラクタにしないと ~Gui() では基底クラスのデストラクタのみが実行されて、解放忘れがおきる。
    for each GuiList {
      // ~Gui() のみが実行されて派生先の開放処理がもれる
      delete gui; 
    }    


NINJAIDX 12