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> | ||
53行: | 53行: | ||
int m_iBaseMoney = 0; | int m_iBaseMoney = 0; | ||
int m_iBaseMonth = 0; | int m_iBaseMonth = 0; | ||
+ | int m_iMoney = 0; | ||
int mf_iBaseSumMoney(); | int mf_iBaseSumMoney(); | ||
public: | public: | ||
58行: | 59行: | ||
CBaseInheritance(int iArgBaseMoney, int iArgBaseMonth); | CBaseInheritance(int iArgBaseMoney, int iArgBaseMonth); | ||
~CBaseInheritance(); | ~CBaseInheritance(); | ||
+ | void mf_vDispValue(); | ||
void mf_vBaseDispValue(); | void mf_vBaseDispValue(); | ||
}; | }; | ||
64行: | 66行: | ||
<span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>基底クラス BaseInheritance.cpp<span>)</span><!-- padding 上 右 下 左--> | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>基底クラス BaseInheritance.cpp<span>)</span><!-- padding 上 右 下 左--> | ||
− | <syntaxhighlight2 lang="cpp" line> | + | <syntaxhighlight2 lang="cpp" line start=100> |
#include "pch.h" | #include "pch.h" | ||
#include "BaseInheritance.h" | #include "BaseInheritance.h" | ||
72行: | 74行: | ||
} | } | ||
− | CBaseInheritance::CBaseInheritance(int iArgBaseMoney, int iArgBaseMonth) | + | CBaseInheritance::CBaseInheritance(int iArgBaseMoney, int iArgBaseMonth) |
− | + | :m_iBaseMoney(iArgBaseMoney) | |
− | + | ,m_iBaseMonth(iArgBaseMonth) | |
+ | ,m_iMoney(0) { | ||
printf("Constructor:CBaseInheritance(int,int)\n"); | printf("Constructor:CBaseInheritance(int,int)\n"); | ||
} | } | ||
83行: | 86行: | ||
int CBaseInheritance::mf_iBaseSumMoney() { | int CBaseInheritance::mf_iBaseSumMoney() { | ||
− | + | m_iMoney = m_iBaseMoney * m_iBaseMonth; | |
+ | return m_iMoney; | ||
} | } | ||
− | void CBaseInheritance:: | + | void CBaseInheritance::mf_vDispValue() { |
int iSumMoney = mf_iBaseSumMoney(); | int iSumMoney = mf_iBaseSumMoney(); | ||
+ | printf("BaseMoney=%d total=%d\n", iSumMoney, m_iMoney); | ||
+ | } | ||
+ | |||
+ | void CBaseInheritance::mf_vBaseDispValue() { | ||
+ | int iSumMoney = m_iBaseMoney * m_iBaseMonth; | ||
printf("BaseMoney=%d\n", iSumMoney); | printf("BaseMoney=%d\n", iSumMoney); | ||
} | } | ||
98行: | 107行: | ||
<span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>派生クラス DeriveInheritance.h<span>)</span><!-- padding 上 右 下 左--> | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>派生クラス DeriveInheritance.h<span>)</span><!-- padding 上 右 下 左--> | ||
− | <syntaxhighlight2 lang="cpp" line> | + | <syntaxhighlight2 lang="cpp" line start=200> |
#ifndef __DERIVEINHERITANCE_H_YONET__ | #ifndef __DERIVEINHERITANCE_H_YONET__ | ||
#define __DERIVEINHERITANCE_H_YONET__ | #define __DERIVEINHERITANCE_H_YONET__ | ||
115行: | 124行: | ||
~CDeriveInheritance(); | ~CDeriveInheritance(); | ||
void mf_vDeriveDispValue(); | void mf_vDeriveDispValue(); | ||
+ | int mf_iDeriveOption(); | ||
int mf_iDeriveSumMoney(); | int mf_iDeriveSumMoney(); | ||
void mf_vDeriveSetOptionValue(int iArgOptionValue); | void mf_vDeriveSetOptionValue(int iArgOptionValue); | ||
122行: | 132行: | ||
<span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>派生クラス DeriveInheritance.cpp<span>)</span><!-- padding 上 右 下 左--> | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>派生クラス DeriveInheritance.cpp<span>)</span><!-- padding 上 右 下 左--> | ||
− | <syntaxhighlight2 lang="cpp" line> | + | <syntaxhighlight2 lang="cpp" line start=300> |
#include "pch.h" | #include "pch.h" | ||
#include "DeriveInheritance.h" | #include "DeriveInheritance.h" | ||
137行: | 147行: | ||
m_iDeriveOption = iArgOption; | m_iDeriveOption = iArgOption; | ||
+ | m_iMoney = mf_iBaseSumMoney() + m_iDeriveOption; | ||
} | } | ||
152行: | 163行: | ||
m_iDeriveOption = iArgOptionMoney; | m_iDeriveOption = iArgOptionMoney; | ||
} | } | ||
+ | |||
+ | int CDeriveInheritance::mf_iDeriveOption() { | ||
+ | return m_iDeriveOption; | ||
+ | } | ||
+ | |||
int CDeriveInheritance::mf_iDeriveSumMoney() { | int CDeriveInheritance::mf_iDeriveSumMoney() { | ||
− | + | m_iMoney = mf_iBaseSumMoney() + m_iDeriveOption; | |
+ | return m_iMoney; | ||
} | } | ||
165行: | 182行: | ||
2つめの派生クラスはオプション金額を複数、配列によって受け取るものを作ります。以下のとおりです。 | 2つめの派生クラスはオプション金額を複数、配列によって受け取るものを作ります。以下のとおりです。 | ||
− | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span> | + | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>配列入力の派生クラス DeriveArrInheritance.h<span>)</span><!-- padding 上 右 下 左--> |
− | <syntaxhighlight2 lang="cpp" line> | + | <syntaxhighlight2 lang="cpp" line start=400> |
#ifndef __DERIVEARRINHERITANCE_H_YONET__ | #ifndef __DERIVEARRINHERITANCE_H_YONET__ | ||
#define __DERIVEARRINHERITANCE_H_YONET__ | #define __DERIVEARRINHERITANCE_H_YONET__ | ||
180行: | 197行: | ||
int m_iSize = 0; | int m_iSize = 0; | ||
int* m_piDeriveOptionArr = nullptr; | int* m_piDeriveOptionArr = nullptr; | ||
− | |||
public: | public: | ||
CDeriveArrInheritance(int iArgMoney, int iArgMonth); | CDeriveArrInheritance(int iArgMoney, int iArgMonth); | ||
188行: | 204行: | ||
void mf_vDeriveSetArrOption(int* piArgOption); | void mf_vDeriveSetArrOption(int* piArgOption); | ||
+ | int mf_iDeriveSumMoney(); | ||
int mf_iDeriveGetArrOption(); | int mf_iDeriveGetArrOption(); | ||
}; | }; | ||
193行: | 210行: | ||
</syntaxhighlight2> | </syntaxhighlight2> | ||
− | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span> | + | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>配列入力の派生クラス DeriveArrInheritance.cpp<span>)</span><!-- padding 上 右 下 左--> |
− | <syntaxhighlight2 lang="cpp" line> | + | <syntaxhighlight2 lang="cpp" line start=500> |
#include "pch.h" | #include "pch.h" | ||
#include "DeriveArrInheritance.h" | #include "DeriveArrInheritance.h" | ||
227行: | 244行: | ||
} | } | ||
− | + | int CDeriveArrInheritance::mf_iDeriveSumMoney() { | |
for (int iScan = 0; iScan < m_iSize; iScan++) { | for (int iScan = 0; iScan < m_iSize; iScan++) { | ||
m_iDeriveOption += m_piDeriveOptionArr[iScan]; | m_iDeriveOption += m_piDeriveOptionArr[iScan]; | ||
} | } | ||
+ | m_iMoney = m_iDeriveOption + mf_iBaseSumMoney(); | ||
+ | return m_iMoney; | ||
} | } | ||
238行: | 257行: | ||
m_piDeriveOptionArr[iScan] = piArgOption[iScan]; | m_piDeriveOptionArr[iScan] = piArgOption[iScan]; | ||
} | } | ||
− | + | mf_iDeriveSumMoney(); | |
} | } | ||
+ | |||
+ | |||
</syntaxhighlight2> | </syntaxhighlight2> | ||
+ | |||
+ | 配列入力を受け付けるコンストラクタCDeriveArrInheritance::CDeriveArrInheritance(int iArgMoney, int iArgMonth, int* piArgOption,int iArgSize)は3つめの引数が、その配列アドレスを受け取り、配列の大きさを4つめの引数で受け取りメンバ変数m_iSizeへ格納します。配列はメンバ関数mf_vDeriveSetArrOption(piArgOption)でそのまま横流しします。mf_vDeriveSetArrOptionでは、配列を自身のクラスの中でコピーするようにm_piDeriveOptionArr = new int[m_iSize]で動的に受け取った大きさの分の配列として生成します。そしてfor分の中で配列のひと要素づつをコピーしていきます。mf_vDeriveSumMoney()を呼び、配列のひと要素づつを足し合わせて、m_iDeriveOptionへ合計を記憶します。CDeriveArrInheritance::mf_vDeriveArrDispValueで基底クラスの月額料金×利用月の合計と自身のクラスで計算したオプション合計金額m_iDeriveOptionに格納し、その値を返却するCDeriveArrInheritance::mf_iDeriveGetArrOptionを使って足し合わせた値をprintf文で表示しています。デストラクタで動的に生成したm_piDeriveOptionArrが保持する実体を消去する処理を入れています。配列を使うとちょっとプログラムが長くなりますね。 | ||
+ | |||
+ | |||
+ | 次に3つめの派生クラスの基底クラスの料金を割り引くクラスを作ります。 | ||
+ | |||
+ | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>割引の派生クラス DeriveDiscountInheritance.h<span>)</span><!-- padding 上 右 下 左--> | ||
+ | <syntaxhighlight2 lang="cpp" line start=600> | ||
+ | #ifndef __DERIVEDISCOUNTINHERITANCE_H_YONET__ | ||
+ | #define __DERIVEDISCOUNTINHERITANCE_H_YONET__ | ||
+ | #if _MSC_VER > 1000 | ||
+ | #pragma once | ||
+ | #endif | ||
+ | #include "BaseInheritance.h" | ||
+ | |||
+ | class CDeriveDiscountInheritance :public CBaseInheritance { | ||
+ | private: | ||
+ | int m_iDeriveOption = 0; | ||
+ | int m_iDeriveMoney = 0; | ||
+ | double m_dRate = 0; | ||
+ | public: | ||
+ | CDeriveDiscountInheritance(int iArgMoney, int iArgMonth); | ||
+ | CDeriveDiscountInheritance(int iArgMoney, int iArgMonth, double dArgRate); | ||
+ | ~CDeriveDiscountInheritance(); | ||
+ | void mf_vDeriveDiscountDispValue(); | ||
+ | |||
+ | void mf_iDeriveSetDiscount(double dRate); | ||
+ | int mf_iDeriveSumMoney(); | ||
+ | }; | ||
+ | #endif | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">cpp <span>(</span>割引の派生クラス DeriveDiscountInheritance.cpp<span>)</span><!-- padding 上 右 下 左--> | ||
+ | <syntaxhighlight2 lang="cpp" line start=700> | ||
+ | #include "pch.h" | ||
+ | #include "DeriveDiscountInheritance.h" | ||
+ | |||
+ | CDeriveDiscountInheritance::CDeriveDiscountInheritance(int iArgMoney, int iArgMonth) | ||
+ | :CBaseInheritance(iArgMoney, iArgMonth){ | ||
+ | printf("Constructor:CDriveDiscountInheritance(int,int)\n"); | ||
+ | } | ||
+ | |||
+ | CDeriveDiscountInheritance::CDeriveDiscountInheritance(int iArgMoney, int iArgMonth, double dArgRate) | ||
+ | :CBaseInheritance(iArgMoney, iArgMonth) { | ||
+ | printf("Constructer:CDeriveDiscountInheritance(int,int,double)\n"); | ||
+ | m_dRate = dArgRate; | ||
+ | mf_iDeriveSumMoney(); | ||
+ | } | ||
+ | |||
+ | CDeriveDiscountInheritance::~CDeriveDiscountInheritance() { | ||
+ | printf("Destructer:~CDeriveDiscountInheritance()\n"); | ||
+ | } | ||
+ | |||
+ | |||
+ | void CDeriveDiscountInheritance::mf_iDeriveSetDiscount(double dArgRate) { | ||
+ | m_dRate = dArgRate; | ||
+ | mf_iDeriveSumMoney(); | ||
+ | } | ||
+ | |||
+ | void CDeriveDiscountInheritance::mf_vDeriveDiscountDispValue() { | ||
+ | int iSumMoney = mf_iDeriveSumMoney(); | ||
+ | printf("DeriveMoney=%d\n", iSumMoney); | ||
+ | } | ||
+ | |||
+ | int CDeriveDiscountInheritance::mf_iDeriveSumMoney() { | ||
+ | m_iMoney = (int)(m_dRate * mf_iBaseSumMoney() + 0.5); | ||
+ | return m_iMoney; | ||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | コンストラクタCDeriveDiscountInheritance(int iArgMoney, int iArgMonth, double dArgRate)は3つめの引数で割引の率を受け取ります。5割引きなら0.5を受け付ける形式です。50%の50とかではないです。そして、割合をm_dRateへ格納します。2つの引数だけ受け取るコンストラクタを使って、後から割合だけを受け取るCDeriveDiscountInheritance::mf_iDeriveSetDiscountというメンバ関数もあります。そしてCDeriveDiscountInheritance::mf_vDeriveDiscountDispValue()で割引した後の金額を表示します。m_dRateはdouble型なので、計算結果が小数まで計算されます。これを四捨五入するために0.5を足して、(int)(計算結果小数)のようにキャストして小数部を切り落としています。通常のお店の計算では四捨五入ではなく、切り捨てされるのが普通ですが、あえて四捨五入にしてみました。小数点第何位や十、百、千の位とかで四捨五入する場合はもっと違うカタチで四捨五入をしなければならないです。ひとつの方法としては、四捨五入する位置が小数第一位に持ってくるようにを一度、10のN乗倍してから、上記と同じ方法で切り落として、そしてもう一度 10の-N乗倍して、元に戻すという感じです。これだと桁あふれや桁落ちが発生しやすいので、別の方法の方が良かったりします。で、いろいろ考えて自分で作ろうとしてしまいがちですが、標準関数で四捨五入をする関数が既に用意されていたりもします。 | ||
+ | |||
+ | |||
+ | これで派生クラスも出そろいました。普通に派生クラスを利用しようとすると以下のようになります。 | ||
+ | |||
+ | <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=800> | ||
+ | #include "pch.h" | ||
+ | #include "BaseInheritance.h" | ||
+ | #include "DeriveInheritance.h" | ||
+ | #include "DeriveArrInheritance.h" | ||
+ | #include "DeriveDiscountInheritance.h" | ||
+ | |||
+ | int main() { | ||
+ | |||
+ | CBaseInheritance objCBaseInheritance(3900, 12); | ||
+ | objCBaseInheritance.mf_vDispValue(); | ||
+ | |||
+ | CDeriveInheritance objCDeriveInheritance2Arg(2900, 12); | ||
+ | objCDeriveInheritance2Arg.mf_vDeriveSetOptionValue(600); | ||
+ | objCDeriveInheritance2Arg.mf_vDispValue(); | ||
+ | |||
+ | CDeriveInheritance objCDeriveInheritance3Arg(2900, 12, 600); | ||
+ | objCDeriveInheritance3Arg.mf_vDispValue(); | ||
+ | |||
+ | int piOptionArr[] = { 300, 500, 400, 390 }; | ||
+ | int iSize = (int)(sizeof piOptionArr / sizeof(*piOptionArr)); | ||
+ | CDeriveArrInheritance objCDeriveArrInheritance(3900, 12, piOptionArr, iSize); | ||
+ | objCDeriveArrInheritance.mf_vDispValue()(); | ||
+ | |||
+ | CDeriveDiscountInheritance objCDeriveDiscountInheritance(3900, 12, 0.5); | ||
+ | objCDeriveDiscountInheritance.mf_vDispValue(); | ||
+ | |||
+ | return 0; | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | アップキャストの話をしている現段階では、上記のメイン関数は普通に派生クラスを使っているだけなので、特に説明もいらないでしょう。基底クラス→一つしかオプション価格を受け取らない派生クラス→複数のオプション価格をうけとる配列を扱う派生クラス→割引を扱う派生クラスの順に動かしています。動かした結果は以下のとおりです。 | ||
+ | |||
+ | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">実行結果<!-- padding 上 右 下 左--> | ||
+ | <syntaxhighlight2 lang="text" line start=900> | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | BaseMoney=46800, total=35700 | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructor:CDriveInheritance(int,int) | ||
+ | BaseMoney=34800, total=35700 | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructer:CDeriveInheritance(int,int,int) | ||
+ | BaseMoney=34800, total=35700 | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructer:CDeriveArrInheritance(int,int,int*,int) | ||
+ | BaseMoney=46800, total=48390 | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructer:CDeriveDiscountInheritance(int,int,double) | ||
+ | BaseMoney=46800, total=23400 | ||
+ | Destructer:~CDeriveDiscountInheritance() | ||
+ | Destructor:~CBaseInheritance() | ||
+ | Destructer:~CDeriveArrInheritance() | ||
+ | Destructor:~CBaseInheritance() | ||
+ | Destructer:~CDeriveInheritance() | ||
+ | Destructor:~CBaseInheritance() | ||
+ | Destructer:~CDeriveInheritance() | ||
+ | Destructor:~CBaseInheritance() | ||
+ | Destructor:~CBaseInheritance() | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | コンストラクタとデストラクタがどういう風に動作するのかがわかるように呼び出されたら、printfで何が呼ばれたかわかるようにしています。勝手に呼ばれることも多いので、わかりやすいです。 | ||
+ | |||
+ | |||
+ | で、これを元にアップキャストって奴をやってみようと思います。こんな行き当たりばったりでサンプルを作っているので、上手いこと行くかはわかりませんが、メイン関数を作り直してみます。 | ||
+ | |||
+ | <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=1000> | ||
+ | #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(); | ||
+ | pCBaseInheritanceUpcast = pCBaseInheritanceUpcastF(2); | ||
+ | pCBaseInheritanceUpcast->mf_vDispValue(); | ||
+ | pCBaseInheritanceUpcast = pCBaseInheritanceUpcastF(3); | ||
+ | pCBaseInheritanceUpcast->mf_vDispValue(); | ||
+ | delete pCBaseInheritanceUpcast; | ||
+ | |||
+ | return 0; | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight2> | ||
+ | |||
+ | このようにサンプルのメインプログラムだけを変えました。基底クラスのポインタ変数を作って、派生クラスを動かした結果を受け取っています。プログラムの中で、動かす派生クラスを選べて、基底クラスを利用するカタチにしてみました。派生クラスを生成するとオブジェクトが出来当たりますが、そのオブジェクトのポインタを返却(return)したときに関数の返却値の型が基底クラスのポインタ型になっています。そして、結果をそのままメイン関数で受け取るので、アップキャストはreturnの型から返却値の型に変換されているところで起こっています。 | ||
+ | |||
+ | |||
+ | 実行した結果は以下のようになります。 | ||
+ | |||
+ | |||
+ | <span style="color: #ffffff; background-color: #555555; padding: 0px 5px 0px 5px; display: inline-block;">実行結果<!-- padding 上 右 下 左--> | ||
+ | <syntaxhighlight2 lang="text" line start=1100> | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructor:CDriveInheritance(int,int) | ||
+ | BaseMoney=34800, total=35700 | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructer:CDeriveArrInheritance(int,int,int*,int) | ||
+ | BaseMoney=34800, total=36520 | ||
+ | Constructor:CBaseInheritance(int,int) | ||
+ | Constructer:CDeriveDiscountInheritance(int,int,double) | ||
+ | BaseMoney=46800, total=23400 | ||
+ | Destructor:~CBaseInheritance() | ||
+ | </syntaxhighlight2> | ||
+ | ちゃんとアップキャストされても、ちゃんと基底クラスのメンバ関数が派生クラスで動作した内容を反映して動いています。でもデストラクタは、呼ばれていないですね。残念なプログラムになっているようです。次の「継承 デストラクタ」の記事でこの問題について対応したいと思います。今のままでは動的に変数をクラス内で生成しているCDeriveArrInheritanceを使ったときにメモリリークが起こってしまいます。動的に確保したint型の配列メモリをプログラム終了後も解放しようとしない現象です。実際にはプログラム終了時にRAII(Resource Acquisition Is Initialization)という機能によって、ほとんどの場合メモリは解放されます。C++では、smart pointerというものに包み込まれた状態になり、動的に確保したメモリ領域を監視しているので、動的に確保されたメモリは適切に開放されます。たとえ途中で例外処理が発生してプログラムが落っこちた場合でも、解放されます。でも、ちゃんとやった方がいいです。上記のような状態は決してメモリリークがおきないとは保証されないので、ちゃんとやった方がいいのです。でも、アップキャストしたら元々のデストラクタが呼ばれないのは困ったものです。うっかりすると危険だわ。 | ||
[[C PlusPlus#C++からの技術|C++]]に戻る | [[C PlusPlus#C++からの技術|C++]]に戻る |