2016-07-25 11 views
-4
#include <stdio.h> 


class abc{ 
    public: 
     abc  *next; 

    protected: 
     int    flags; 
     const char * name; 
     const char * comments; 

    public: 
     abc(const char *name, const char *comments, int flags); 

     virtual ~abc() { 
      printf("\nReached at virtual ~abc\n"); 
      printf("Returning from at virtual ~abc\n"); 
     } 
}; 

class def: public abc{ 
    public: 
     def (const char *myname, const char *mycomments, 
       int myflags): abc(myname, mycomments, myflags) 
     { 
      printf("\nreached at def\n"); 
      printf("name=%s; comments=%s\n", myname, mycomments); 
      printf("Returning from def\n"); 
     } 
}; 

class ghi: public def{ 
    public: 
     ghi(const char *myname2, const char *mycomments2, 
      int myflags2): def(myname2, mycomments2, myflags2) 
     { 
      printf("\nreached at ghi\n"); 
      printf("name=%s; comments=%s\n", myname2, mycomments2); 
      printf("Returning from ghi\n"); 
     } 
}; 

class jkl: public def{ 
    public: 
     jkl(const char *myname2, const char *mycomments2, 
      int myflags2): def(myname2, mycomments2, myflags2) 
     { 
      printf("\nreached at ghi\n"); 
      printf("name=%s; comments=%s\n", myname2, mycomments2); 
      printf("Returning from ghi\n"); 
     } 
}; 

ghi myVar("myVar", "Testing it", 0); 
jkl myVar2("myVar2", "Testing it Again", 0); 

abc::abc(const char *name, const char *comments, int flags) : next(0){ 
    printf("\nreached at abc::abc\n"); 
    printf("name=%s; comments=%s\n", name, comments); 
    printf("Returning from abc:abc\n"); 
} 



int main(void){ 
    printf("\nrunning main function\n"); 
    printf("ending main function\n"); 
    return 0; 
} 

出力:C++仮想継承

reached at abc::abc 
name=myVar; comments=Testing it 
Returning from abc:abc 

reached at def 
name=myVar; comments=Testing it 
Returning from def 

reached at ghi 
name=myVar; comments=Testing it 
Returning from ghi 

reached at abc::abc 
name=myVar2; comments=Testing it Again 
Returning from abc:abc 

reached at def 
name=myVar2; comments=Testing it Again 
Returning from def 

reached at ghi 
name=myVar2; comments=Testing it Again 
Returning from ghi 

running main function 
ending main function 

Reached at virtual ~abc 
Returning from at virtual ~abc 

Reached at virtual ~abc 
Returning from at virtual ~abc 

私は理解していない:

  • はどの関数が仮想〜ABCは呼ばれているのですか?
  • なぜプログラムの最後に実行されていますか?
  • 機能の目的は何ですか?
+3

あなたはどこで 'virtual'継承を使っていると思いますか?私はまさにそれを引用することを意味します。 – Yakk

+0

@Yakk仮想継承は例ではコード化されていませんが、virtual〜abcがどのように呼び出されているかを知りたい..... – Vineet1982

+1

このプログラムには仮想継承はありません。あなたはあなたの質問を再考したいかもしれません。 –

答えて

0

~abcは、abcのデストラクタです。これは、オブジェクトがもはや必要でないときにそれを破壊する関数です。

プログラムの終わりには、すべてのオブジェクトが破棄されます。そのため、プログラムはすべてのデストラクタを呼び出します。それらの行を印刷するようにデストラクタを定義しました。

また、ツリー内のすべてのオブジェクトはabcから継承されているため、それらはすべてデストラクターを継承します。 2つのオブジェクト、ghijklを宣言します。彼らはプログラムの終わりに破壊されなければならないので、彼らはabcから継承したデストラクタを呼び出します。

デストラクタは、メモリがリークしないようにオブジェクトをカスタム方法で破棄するために使用されます。たとえば、オブジェクトに他のオブジェクトへのポインタがある場合は、そのポインタを安全のためnullptrに設定します。

すべてのオブジェクトにデフォルトのデストラクタがありますが、デフォルトで何も印刷されないことに注意してください。なぜなら、それらのオブジェクトが存在していなかったからです。

1

仮想継承はではありませんあなたがしたこと。仮想関数を持つクラスの静的継承を行いました。

疑問は仮想機能に関連していません。

  1. グローバル変数:myVarmyVar2グローバルです:彼らはそれを終了した後、メイン入る前に作成され、破棄されます。デストラクタが仮想であるかどうかという事実は、この場合、無関係です。
  2. コンストラクタは、メンバーシップと派生の順に呼び出されます。デストラクタは、コンストラクタとは逆の順序で呼び出されます。 abdは、defghiの両方の破壊チェーンで呼び出されます。 ghidefデストラクタを冗長にしなかったので、あなたはそれを見ません。

仮想関数による実行時ポリモーフィズムには、ポインタまたはベースへの参照が必要です。

value変数を直接使用すると、仮想ディスパッチは使用されません。