Cpp クラス 継承 デストラクタ 新しいページはコチラ
提供: yonewiki
(→クラス 継承 デストラクタ) |
|||
5行: | 5行: | ||
<tr> | <tr> | ||
<td style="width:1px;"></td> | <td style="width:1px;"></td> | ||
− | <td class="mbox-text plainlist" style="">本来の表記は「<b><span id="RealTitle" style="font-size:large;">C++ クラス 継承 デストラクタ</span></b>」です。この記事に付けられた題名は{{記事名の制約}}から不正確なものとなっています。</td> | + | <td class="mbox-text plainlist" style="">本来の表記は「<b><span id="RealTitle" style="font-size:large;">C++(Cpp) クラス 継承 デストラクタ</span></b>」です。この記事に付けられた題名は{{記事名の制約}}から不正確なものとなっています。</td> |
</tr> | </tr> | ||
</table> | </table> | ||
49行: | 49行: | ||
</syntaxhighlight2> | </syntaxhighlight2> | ||
+ | 16行目の | ||
+ | |||
+ | <syntaxhighlight2 lang="cpp"> | ||
+ | virtual ~CBaseInheritance(); | ||
+ | </syntaxhighlight2> | ||
これだけで、基底クラスが消滅したときにアップキャストされた基底クラスが派生クラスのデストラクタを保持することになります。つまり派生クラスのデストラクタが動く可能性が出てきました。しかし、今回作ったメイン関数では、ポリモーフィズムで形態を変えるごとに基底クラスが消滅しないため、1回目の派生クラスからのアップキャスト生成と2回目のアップキャスト生成に対しては消滅処理がされないため、派生クラスのデストラクタは呼ばれません。基底クラスのデストラクタも呼ばれません。 | これだけで、基底クラスが消滅したときにアップキャストされた基底クラスが派生クラスのデストラクタを保持することになります。つまり派生クラスのデストラクタが動く可能性が出てきました。しかし、今回作ったメイン関数では、ポリモーフィズムで形態を変えるごとに基底クラスが消滅しないため、1回目の派生クラスからのアップキャスト生成と2回目のアップキャスト生成に対しては消滅処理がされないため、派生クラスのデストラクタは呼ばれません。基底クラスのデストラクタも呼ばれません。 | ||
58行: | 63行: | ||
Constructor:CBaseInheritance(int,int) | Constructor:CBaseInheritance(int,int) | ||
Constructor:CDriveInheritance(int,int) | Constructor:CDriveInheritance(int,int) | ||
− | BaseMoney=34800 | + | BaseMoney=34800, total=35700 |
Constructor:CBaseInheritance(int,int) | Constructor:CBaseInheritance(int,int) | ||
Constructer:CDeriveArrInheritance(int,int,int*,int) | Constructer:CDeriveArrInheritance(int,int,int*,int) | ||
− | BaseMoney=34800 | + | BaseMoney=34800, total=36520 |
Constructor:CBaseInheritance(int,int) | Constructor:CBaseInheritance(int,int) | ||
Constructer:CDeriveDiscountInheritance(int,int,double) | Constructer:CDeriveDiscountInheritance(int,int,double) | ||
− | BaseMoney=46800 | + | BaseMoney=46800, total=23400 |
Destructer:~CDeriveDiscountInheritance() | Destructer:~CDeriveDiscountInheritance() | ||
Destructor:~CBaseInheritance() | Destructor:~CBaseInheritance() | ||
</syntaxhighlight2> | </syntaxhighlight2> | ||
+ | |||
+ | それで、メイン関数で形態を変える都度、消滅する処理をいれると、以下のようになります。 | ||
+ | |||
+ | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>メイン関数 InheritanceMain.cpp<span>)</span><!-- padding 上 右 下 左--> | ||
+ | <syntaxhighlight2 lang="cpp" line start=200> | ||
+ | #include "pch.h" | ||
+ | #include "BaseInheritance.h" | ||
+ | #include "DeriveInheritance.h" | ||
+ | #include "DeriveArrInheritance.h" | ||
+ | #include "DeriveDiscountInheritance.h" | ||
+ | |||
+ | CBaseInheritance* pCBaseInheritanceUpcastF(int iSelectDerive) { | ||
+ | int piOptionUpcastArr[] = { 800, 200, 500, 220 }; | ||
+ | int iSize = (int)(sizeof piOptionUpcastArr / sizeof(*piOptionUpcastArr)); | ||
+ | switch (iSelectDerive) { | ||
+ | case 1: | ||
+ | return new CDeriveInheritance(2900, 12); | ||
+ | case 2: | ||
+ | return new CDeriveArrInheritance(2900, 12, piOptionUpcastArr, iSize); | ||
+ | default: | ||
+ | return new CDeriveDiscountInheritance(3900, 12, 0.5); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | int main() { | ||
+ | |||
+ | CBaseInheritance* pCBaseInheritanceUpcast; | ||
+ | pCBaseInheritanceUpcast = pCBaseInheritanceUpcastF(1); | ||
+ | pCBaseInheritanceUpcast->mf_vDispValue(); | ||
+ | delete pCBaseInheritanceUpcast; | ||
+ | |||
+ | pCBaseInheritanceUpcast = pCBaseInheritanceUpcastF(2); | ||
+ | pCBaseInheritanceUpcast->mf_vDispValue(); | ||
+ | delete pCBaseInheritanceUpcast; | ||
+ | |||
+ | pCBaseInheritanceUpcast = pCBaseInheritanceUpcastF(3); | ||
+ | pCBaseInheritanceUpcast->mf_vDispValue(); | ||
+ | delete pCBaseInheritanceUpcast; | ||
+ | |||
+ | return 0; | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | これなら、なんとなく思い描いたとおりの動作になります。 | ||
+ | |||
+ | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">実行結果<!-- padding 上 右 下 左--> | ||
+ | <syntaxhighlight2 lang="text" line start=300> | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructor:CDriveInheritance(int,int) | ||
+ | BaseMoney=34800, total=35700 | ||
+ | Destructer:~CDeriveInheritance() | ||
+ | Destructor:~CBaseInheritance() | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructer:CDeriveArrInheritance(int,int,int*,int) | ||
+ | BaseMoney=34800, total=36520 | ||
+ | Destructer:~CDeriveArrInheritance() | ||
+ | Destructor:~CBaseInheritance() | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructer:CDeriveDiscountInheritance(int,int,double) | ||
+ | BaseMoney=46800, total=23400 | ||
+ | Destructer:~CDeriveDiscountInheritance() | ||
+ | Destructor:~CBaseInheritance() | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | という感じで、きちんとそれぞれの派生クラスのデストラクタが動くようになります。よくクラスのデストラクタにはvirtualを付けとけ、というようなことを言う、なんでもvirtual ~xxxデストラクタ主義を唱える人がいますが、自分はアップキャストで使うクラスだけに付ければよいと思います。そんなアップキャストするかどうかも意識していない基底クラスを利用すれば、デストラクタがどこではたらくかを意識していないということになるので、雑なプログラムになってしまいます。ちゃんと管理した方が良いと思います。設計図でしっかりと管理してほしいな。なんでもvirtualでもいいですけど。不要なデストラクタが省略できなくなるよ。 | ||
+ | |||
+ | |||
+ | それってわかりにくくないかな。 | ||
+ | |||
+ | |||
+ | 好きなようにしてもらえればいいですけど。 | ||
+ | |||
[[C PlusPlus#C++からの技術|C++]]に戻る | [[C PlusPlus#C++からの技術|C++]]に戻る |