Cpp クラス const 新しいページはコチラ
提供: yonewiki
(→constメンバ関数) |
(→constメンバ変数) |
||
176行: | 176行: | ||
コンストラクタの関数の後に : を記述して、その後ろに引数を定義していきます。文字あるいは文字列のような一重引用符や二重引用符のリテラルを()の中に記述することもできます。この初期化は特にconstでないメンバ変数でなくても初期化できます。面倒ですが…。 | コンストラクタの関数の後に : を記述して、その後ろに引数を定義していきます。文字あるいは文字列のような一重引用符や二重引用符のリテラルを()の中に記述することもできます。この初期化は特にconstでないメンバ変数でなくても初期化できます。面倒ですが…。 | ||
+ | |||
+ | |||
+ | ==const外し(const_cast)== | ||
+ | const_castを使うといろいろな場面でconstで指定されている変数(ポインタ変数やオブジェクトも含める)であったものをconst無しの扱いに変更が出来ます。それじゃ、constでは保護されないじゃん。なんじゃそりゃ。って思うやもしれませんが、constというものはそういうものです。では、どれくらいのことがやれるのか試してみましょう。 | ||
+ | |||
+ | |||
+ | まず、メンバ関数の引数はconstではないのに、呼び出す側のプログラムではconstになってしまっている場合。 | ||
+ | |||
+ | 例えばsample_main.cpp側で | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | const int* constpnValue = new int(2000);//★20. | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | ★20.部分のように値を変えられたくないint型のポインタ変数を実体化してconstに指定している場合で、以下に示すメンバ関数のようにint*型の引数を必要としている関数があった場合。 | ||
+ | |||
+ | |||
+ | Const001.h(メンバ関数追加) | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | class CConst001 | ||
+ | { | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | public: | ||
+ | void mfpub_Set_m_nValueConstpPara(int* pnPara1); | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | Const001.cpp(メンバ関数追加) | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | void CConst001::mfpub_Set_m_nValueConstpPara(int* pnPara1){ | ||
+ | *pnPara1 = mpub_constnValue; | ||
+ | m_nValue = 1000; | ||
+ | printf("mfpub_Set_m_nValue\n", mpub_constnValue); | ||
+ | printf("m_nValue =%d\n", m_nValue); | ||
+ | printf("mpub_constnValue=%d\n", mpub_constnValue); | ||
+ | } | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | のように引数の中身が書き換えられてしまう関数があった場合でそのまま、呼び出し側のconst変数を使わなければならないという、ありえないような状況に対応するならば、メイン関数の呼び出しは以下のようにcastすることで呼び出せてしまいます。 | ||
+ | |||
+ | 例えばsample_main.cpp側で | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | int _tmain(int argc, _TCHAR* argv[]) | ||
+ | { | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | CConst001* CConst001_Instance = new CConst001; | ||
+ | const int* constpnValue = new int(2000); | ||
+ | CConst001_Instance->mfpub_Set_m_nValueConstpPara(const_cast<int *>(constpnValue));//★21. | ||
+ | … | ||
+ | 省略 | ||
+ | … | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | ★21.部分のように引数に | ||
+ | |||
+ | '''const_cast<int *>(constpnValue)''' | ||
+ | |||
+ | ワ、ワイルドだろ?っていう、そんな感じですが、constな・ん・か、そんなの関係ねぇ~。そんなの関係ねぇ~。ハイ。おっぱっぴ~。こういう具合にconstの効力なんてのは、外そうと思えば外せるわけです。この場合はC++プログラムの理念から外れていることになります。今回の場合はメンバ関数内で書き換えられるわけだからメイン関数側でconstに指定したものを引数にしたことが間違っていることになります。メンバ関数の名前がSetって名前だから、本来は書き換えられるべきでない仕様のハズ。だとしたら、メンバ関数名がおかしいとも考えられるし、間違えて無意味に引数を書き換えてしまうようなメンバ関数になってしまっている可能性もあります。そうするとメンバ関数の引数側でconst int*という型にしておかなかったのが間違いだとも考えられます。 | ||
+ | |||
+ | |||
+ | つまり、const_castを使っているという事は何かの歯車が噛み合っていないそんな感じです。それでも、歯車が壊れない程度にガチャガチャ回し続けている社会というのは、よくあります。const_castはどんなことがあろうと、一日たりとも止めることが出来ない社会を成り立たせるために突き進めるためにある。そういうことです。 | ||
+ | |||
+ | |||
+ | 以降でも、いくつかconst_castのパターンを記述していこうと思いますが、誰がどう悪いのかは説明しません。やろうと思えばできる。家のような大切な鍵でもキーインロックをやらかしてしまったら鍵の救急車なる謎の部隊を呼ぶことができて、簡単に施錠を解除してくれます。それで家の中に入れたとき、あぁ世界は素晴らしいって思えると思います。あぁC++は素晴らしい。あれ?なんか違うか? | ||
+ | |||
+ | |||
+ | と、まぁうまいこと例えたつもりです。続きのパターンはまたぼちぼち書いていきます。 | ||
+ | |||
+ | |||
+ | (鋭意執筆中) | ||
長い文章になってしまいましたが、概ねの説明は完了です。 | 長い文章になってしまいましたが、概ねの説明は完了です。 |