C++を使ってチームで開発していると、一度ぐらいは必ず遭遇したことがある恐怖の間違いがあります。それが、コンパイルエラーを取り除くためにアクセス指定子を修正すればよいという考え方です。具体的にどういうことか見ていきましょう。

上のようなクラス定義があったとします。このクラスでは、セオリー通りデータメンバを非公開にしています。そして、データメンバbar_は、メンバ関数を呼び出したときに適切に操作されるようになっていると考えてください。get_barやset_barのようないわゆるアクセッサは設けず、あくまでもfooクラスの実装の詳細という位置づけです。

このfooクラスのクライアントコードを書いている担当者が、fooクラスを何とか使いこなそうとして、実装を理解するためにソースコードを読むことはよくあります。クラスはブラックボックスとして考えればよいなどという建前論は大抵無意味です。遅かれ早かれ、彼はfooクラスの内部状態を保持しているデータメンバbar_を見つけることでしょう。そして、このbar_の値を外部から参照したいと考えるかもしれません。

C++に不慣れなのか、privateというアクセス指定子を見落としたのかは知りませんが、fooクラスのクライアントコードで直接foo::bar_を参照するようなコードを書いてしまい、彼は、当然のことながら、コンパイルエラーに遭遇しました。エラーメッセージを見てすぐに、エラーの原因がfoo::bar_がprivateだからということに気付きました。

ここから問題行動が始まります。

foo::bar_はprivateであり、外部から参照することはできません。ですので、この値を参照してどうにかするというのは、そもそもの設計に問題があるわけです。しかし、彼がこれまでに書いたコードはfoo::bar_の値を参照できることに強く依存しており、今さらそれらを全部捨てて書き直すのは大変です。そこで、こっそりprivateをpublicに書き換えてしまいます。これで彼が書いたコードはコンパイルに成功し、期待通りに動作しました。”彼は”万々歳です。

こんな冗談のようなことが実際にはしばしば発生します。データメンバをprivateにしていたのは、彼のような無茶をする相手からオブジェクトを保護するために、fooクラスの設計者がそのようにしたわけです。いわば、fooクラスの免疫機構のようなものです。彼の行為はその免疫機構を破壊する行為であり、fooクラスとそのオブジェクトを病原体(=オブジェクトを破壊するようなクライアントコードによる間違った操作)に対して無防備にしてしまいます。

foo::bar_がpublicになれば、今や自在にfoo::bar_を外部から変更できるようになってしまいます。もはや破綻は時間の問題です。

これはC++に限った話ではなく、JavaでもC#など、情報隠蔽ができるプログラミング言語すべてでいえることです。