readonly publicっつーのはないもんか。
俺ルールとして、「constなメンバはpublicにしてもよい」というのがある。
class Nanika { int var; public: int const cons_t; };
そんなことしてメンバ晒せば、結合度上がっちゃう、という指摘はもっともなんだけど、getXXXとかのアクセサを作っても、それはほとんど一緒なはず。
一緒じゃない点に、アクセサを使えば、将来、その値が毎回再計算しないといけないとかになった場合に、変更が外部へ及ばなくてよろしい。
class Nanika { int var; int const cons_t; public: int getConst() const { return cons_t; } };
こうしとけば、
class Nanika { int var; int const cons_ts[10]; public: int getConst() const { return sum( cons_ts ); } };
こーんな変更をしてしまっても、外部に影響が無くて嬉しい。
しかし、そこが嫌いなのである。
と、いうのは、将来変更が楽である、ということは、つまり、「将来変更する意図があるよ」、ということを意味している。
いや、意味してるかもしれないし、意味してないかもしれない。それはコードからはわからない。
で、そういうコードから意図がわからないというのが嫌だ。
そこで、アクセサを使わないことによって、「この部分は、将来変な変更はしない!」という表明をする、というわけだ。
あと、メソッド呼び出しにしないことによって、その部分は「副作用が無い」ということを断言できるのも大きい。と、いうか、そっちのほうが重要か。
というわけで、
- 将来変更しない
- 副作用が無い
というのを表明するのに役立つので、アクセサは意図的に書かないことがある、というような話。
と、そこまではよいのだけど、C++のvectorとかは困ったことに、constにしてしまうと使いものにならない。
class Nanika { vector<int> const values; public: Nanika( int a, int b, int c ) { values.push_back( a ); values.push_back( b ); values.push_back( c ); } };
これが無理。
class Nanika { vector<int> const values; public: Nanika( int a, int b, int c ) : values = {a,b,c} { } };
こんなふうに書ければいいんだけど。
というわけで、コンテナ使いはじめると、constをとって、アクセサを用意しないと気持ちが悪い。というような感じになってしまう。
class Nanika { vector<int> values; public: Nanika( int a, int b, int c ) { values.push_back( a ); values.push_back( b ); values.push_back( c ); } int get_value( int n ) { return values[n]; } };
そんで、自分の中でだけは、constじゃないreadonly_publicみたいなのが無いかなー、とかいうようなことをたまに妄想する。
class Nanika { readonly_public: vector<int> values; public: Nanika( int a, int b, int c ) { values.push_back( a ); values.push_back( b ); values.push_back( c ); } };
いや、そういうのは、気分の問題なのでいいんだけど。
あと、こういうことを読むときは、「僕は仕事でC++とかオブジェクト指向とかやったことない」というのを念頭に置いて読んでいただけると幸い。全部趣味だから。
仕事でやるときは、誰がどう書き換えるかわかんないので(全ての意図が伝わるとは限らない)、なるべくそこのルールにのっとった書きかたをしたほうがよいです。ルールが決まってないときは世間で標準とされてるスタイルで。上の場合は、アクセサを書くように。(Exceptional C++ Styleには、publicメンバー変数は邪悪だと書いてあった。)