- 締切済み
const で手軽にいんぺいする方法
C++ ではいんぺいの仕組みの一つに const があります。 変数の定義時によく使われているのをよく目撃します。 /** * const int N = 1000; */ 私は現在,変数の定義ではない場所で const を使いたいと思っています。 例えば以下のようなソースを書くにはどうすればよいでしょうか。 /** * int N = 1000; /* ここで変数を定義 */ * * ここらへんでは N をいろいろ変更したい * * ここから先は N を変更したくない */ “ここから先は” というのがミソです。 N についてセッタ setN(int n) やゲッタ getN() を作れば,何とかなるのは分かります。 ただそんなに大げさではなく const を使って手軽にいんぺいできる方法が知りたいです。 C++ 超初心者につき,マヌケな質問をしているかもしれませんが,ご教授いただけると幸いです。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- jacta
- ベストアンサー率26% (845/3158)
もし、同じ関数の中だけで、変更可能かどうかを制御したいのであれば、 void func() { int N = 1000; // ここでは変更可能 { const int& tN = N; const int& N = tN; // ここでは変更不可 } // ここでは変更可能 } というやり方でもよいかと思います。 #4の回答にあるように、実行時にエラー検出したいのであれば、一般的にはラッパークラスを作るしかありません(MMUを自分で制御できるような場合には、ラッパークラスなしでもどうにかなる可能性があります)が、その場合、ラッパークラス作成の手間以外に、エラー処理を記述しないといけないので、大変な手間がかかります。例外を使った場合、今度はコードを例外安全にするのが面倒になってきますね。
- Kenichi31980
- ベストアンサー率46% (7/15)
constは、文法上その変数およびオブジェクトに対する変更を行わせないものです。 なので、エラーの検出は、コンパイル時に行われます。 たとえば、プログラム中で絶対誰にも変えられたくない定数 PIとか をconst宣言するといいわけです。 これは、int hoge(const int foo)などとした場合、関数内でのfooへの変更をコンパイラでエラーとして検出してくれます。 お読みしたところ、目標が 「コンパイラによるエラーの回避」でなく 「実行時のエラーの回避」であるならば、 class myInt を宣言して、 オペレーターの定義 operater=,operater+,operater-,operater* メソッドの定義 setReadOnly(),setReadWrite()などをご自身でされるのがよいかと思います。 C++とは、必要な機能は自身でクラスを利用して作成する、 そういう言語(というよりむしろ環境)なのだと思います。
お礼
ご回答ありがとうございます。 クラスを定義する方法は思いつきもしませんでした! C++ への理解が深まれば是非、挑戦してみたいです。
- jacta
- ベストアンサー率26% (845/3158)
constが隠蔽の手段でないことはすでに指摘が挙がっているとおりです(ちなみのアクセス制御の手段でもありません)。 そうすることが良いかどうかは別として、単にお望みの機能を実現するだけであれば、 int N = 1000; // ここでは変更可能 #define N int(N) // ここでは変更不可 #undef N // ここでは再び変更可能 とすればよいかと思います。
お礼
ご回答ありがとうございます。 #define は勉強不足でよく理解しておりませんので今後、ぜひ勉強しようと思います。
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
まず、C++の const は、「隠蔽」の手段ではありません。 普通、隠蔽は、データ構造を含めた用語で、int N という型も変数名もわかってしまえば、それは隠蔽ではありません。 ゲッタが隠蔽のひとつとして使われるのは、(実装としては単純に n を返してるだけかもしれませんが)何を返しているのか、わからなくするためです。 const は、(内容が変更できないという意味での)アクセス制御のひとつです。 さて、その上で、const 宣言したものが実は変更可能であるというのは、大変危険なので、このような使い方はおすすめできません。 また、C++の const int などは、実体としては、型のある define に近いですが。(Cの const int は、書き換えできない int 型の変数です) さて、それでも、やってみようと思えば、 int N = 1000; int *ptrN = &N; const int *ptrConstN = &N; とでもすれば、*ptrN からは、変更可の、 *ptrConstN からは、変更不可として、同じものをアクセスすることができます。
お礼
ご回答ありがとうございます。
- dyna_1550
- ベストアンサー率34% (122/353)
{}を使ってスコープを狭くすると、似たようなことができそうです。 ただし、スコープの中と外で受け渡しの変数が必要です。 int tmp_N; // 受け渡し用 { // スコープを狭くするだけのカッコ int N=1000; /* 実装 */ tmp_N=N; } // スコープを狭くするカッコ終わり const N=tmp_N; 果たして動くかどうか・・・ ごみレスだったらすみません。
お礼
ご回答ありがとうございます。 スコープの活用については勉強してみたいと思います。
お礼
ご回答ありがとうございます。 ラッパークラスは初耳の用語ですので是非、調査して、頭の片隅にいれておきます。