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メンバー変数は邪悪だと書いてあった。)