この文書の現在のバージョンと選択したバージョンの差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
ja:cpp:class [2017/05/13 13:40] kota [覚書] |
ja:cpp:class [2017/05/28 18:09] (現在) kota [覚書] |
||
---|---|---|---|
ライン 4: | ライン 4: | ||
===== 覚書 ===== | ===== 覚書 ===== | ||
+ | 以下親クラス-子クラス、基底クラス-派生クラスという言葉がでてくるが、親<->基底、子<->派生で読み換え可。(混じってるだけ) | ||
=== 継承とvirtual === | === 継承とvirtual === | ||
* 継承関係にある Base, Derived の2クラスが、同じ名前の関数func()を持っているとする。 | * 継承関係にある Base, Derived の2クラスが、同じ名前の関数func()を持っているとする。 | ||
ライン 10: | ライン 11: | ||
* func()が親クラスでvirtualで宣言されていない時 : Base::func() が呼び出される | * func()が親クラスでvirtualで宣言されていない時 : Base::func() が呼び出される | ||
* ポリモーフィズムを利用する場合は大概、派生クラスの関数のほうが呼ばれて欲しいだろうので、virtualで宣言すべきだろう | * ポリモーフィズムを利用する場合は大概、派生クラスの関数のほうが呼ばれて欲しいだろうので、virtualで宣言すべきだろう | ||
+ | * virtualでない場合、例えば親クラスの関数(子クラスでは再定義されていない)でfunc()を呼び出している場合、Derived *obj = new Derived() のようにしていたとしても、(親クラスの世界の中でfunc()をよびだしているので)Base::func()が呼ばれてしまう。virtualで宣言しておけばDerived::func()がちゃんと呼ばれる。 | ||
+ | * あえて基底クラスのほうのfunc()を呼びたければ、スコープ解決演算子を使ってBase::func() と明示的に指定して呼び出せばよい。 | ||
ライン 20: | ライン 23: | ||
* Initialize() みたいな関数を作った時など注意したほうがいいかも。 | * Initialize() みたいな関数を作った時など注意したほうがいいかも。 | ||
- | === (仮想メンバ関数をもつ)親クラスのでコンストラクタはvirtualでなくてはならない=== | + | === (仮想メンバ関数をもつ)親クラスのでデストラクタはvirtualでなくてはならない=== |
* ポリモーフィズムを利用する(Parent *obj = new Daughter() のように使う)ことを想定 | * ポリモーフィズムを利用する(Parent *obj = new Daughter() のように使う)ことを想定 | ||
* デストラクタが virtual でない場合、親クラスの型のポインタを delete した際には親クラスのデストラクタしか呼ばれない | * デストラクタが virtual でない場合、親クラスの型のポインタを delete した際には親クラスのデストラクタしか呼ばれない |