JavaにC++のconstがあったらいいなぁと思った時期があったけど
やっぱり、mutableやconst_castと縁を切ることができないので駄目な気がした。
あったらいいなと思ったのはconst int hoge;とかじゃなくて、もちろんconstなメソッド。
constはメンバ関数にconstなメソッドであることを宣言することで、
「変更不可」を表し、
「constな参照、constなポインタからはconst(変更不能)なメンバ関数しか呼び出せなくする」
というdefensiveな機構で、finalとは似て非なるものなのですが、
constについて考える時、Javaがfinalにした意味がわかるような気がする。
class Hoge { public: Hoge (int value) : value_(value) {} virtual ~Hoge (){} int getValue() const { return value_; } void setValue(int value) { value_ = value; } private: int value_; };
というクラスがあった場合、getValueはconstなメンバ関数。
setValueは自身を変更してしまうのでconst性を持つことができない。
よって、
Hoge* pHoge = new Hoge(100); const Hoge& refHoge = *pHoge;
とすると、
pHoge->setValue(100);
pHoge->getValue();
は正当な呼び出しだが、
refHoge.getValue();
は赦されても、
refHoge.setValue(1);
は駄目で、
constな参照であるrefHogeからはconstでないsetValueを呼び出せない。
また、constであるgetValueはその中身でメンバ変数を書き換えることもできない。
これは凄く堅牢な仕組みに見える。
が、実際これを打ち破る術がconst_castとmutableで、
const_cast<Hoge&>(refHoge).setValue(1);
はconst性を除去するので不法ではないし、
メンバ変数value_をmutableな変数であると宣言すれば、
setValueをconstなメンバ関数であるとすることもできる。(変更しているが変更不可のふりができる)
const_castはconst性の付与と除去のためだけに使われ、
mutableはconstなメンバ関数から変更可能であるという指定に使われる。
結局のところ、
これら不法の整理をすることを考えると一筋縄ではconstを導入することはできないだろう、
と思われるのだ。
Javaが取り込むにはちょっと荷が重い気がする。
やっぱりC++は自由と不自由のいたちごっこみたいな言語だ。
const好きだけどね。
まる。
Pythonでも__setattr__などでごにょごにょやればconst的なメソッドは作れるかもしれないけど、
結局constな参照などが使えないと魅力半減、
で、もしそういうのができても「constだけど変更したい」とか言われるのがオチ。
ということで他言語でも殆ど採用されない機構なのであった。