ある人が「ぐへへお姉ちゃんパンツ何色」と質問するのは、お姉ちゃんオブジェクトの保持するpants_color変数を取得しようとする手続きと見ることが出来ます。つまり
oneechan.pants_colorを取得しようとしているわけです。
ではどうすればいいのでしょうか?
考えてみましょう。直接パンツを見ればpants_colorを取得することができますね。
クラスを使わないとすればこんな書き方が考えられます。
struct oneechan{構造体でひな形を宣言します。そして
int pants_color;
};
oneechan homuhomu;こんな感じでしょうか。 ほむほむを宣言します。
するとhomuhomu.pants_colorでほむほむのパンツの色にアクセスできます。
しかしこれには致命的な欠点があります。
homuhomu.pants_color = 0xFFFFFF;……そう、色を勝手に変えられてしまうのです!
たとえばこんなミスをしたらどうなってしまうでしょうか?
if(homuhomu.pants_color = 0x000000){なんかかんか}パンツの色が黒かどうか確認しようとして、黒のパンツを履かせてしまうという致命的なバグを引き起こしてしまいます!
そのうえ構造体はその性質上、内部の値がすべてどこからでも参照できてしまします!
これは非常によろしくない。そのために、クラスです。
クラスは「カプセル化」として隠蔽の仕組みを備えています。というわけでクラスを用いてひな形を作ってみましょう。
class oneechan{こうなります。
private:
int pants_color;
};
パンツの色はプライベート変数になったため、
oneechan homuhomu;こんなコードを書いてもコンパイラが怒ってくれます。
homuhomu.pants_color = 0x000000;
具体的に言うと「お姉ちゃんのパンツの色はプライベートなのでアクセスできないぞっ(意訳)」と叱ってくれるはずです。
これでお姉ちゃんのパンツの色を勝手に変更されてしまう問題は無くなったかに見えます。
けれどももう一つ、別の問題が生まれたことに気づくでしょうか?
std::cout << std::hex << std::showbase << homuhomu.pants_color << std::endl;お姉ちゃんのパンツの色を16進数で表示してね!というと……再びコンパイラが「お姉ちゃんのパンツの色はプライベートなのでアクセスできないぞっ」 と怒ります。そう、隠蔽されてしまったパンツの色を確認するにはどうしたらいいのでしょうか?
こうしましょう。
class oneechan{パブリックにset_pants_color()メソッドとget_pants_color()メソッドを追加しました。
public:
int get_pants_color() const;
void set_pants_color(int color);
private:
int pants_color;
};
int oneechan::get_pants_color() const {
return pants_color;
};
void oneechan::set_pants_color(int color) {
pants_color = int color;
};
パンツの色にアクセスするためにはこのメソッドを利用します。
(2011/12/07追記:getterにはconstを付けるように!との指摘を受けました。ありがとうございます。)
homuhomu.get_pants_color()これでパンツの色を取得できます。パンツの色はprivate なので「外部から勝手にアクセスする」ことはできません。しかしお姉ちゃん自身からは参照することができるのです。だからお姉ちゃんにいったん質問を投げ、値を教えてもらうという手順をふむのです。
こうしてお姉ちゃんのパンツの色の安全は確保されました。
C++においてクラスの変数は明示的にpublicを付けない限りprivateです。よほど熱心にパンツの色を公開しようとしているお姉ちゃんでない限り、スカートを身につけてパンツの色を隠蔽していますし、勝手に履き替えさせたりしてくれません。
「ぐへへお姉ちゃんパンツ何色」という質問、これは非常に行儀のよい手続きです。まずお姉ちゃんはパンツの色をカプセル化して隠蔽しています。お姉ちゃん本人以外が勝手にアクセスすることはできません。
質問者はそれを理解してお姉ちゃんのプライベートなパンツの色にアクセスするメソッドを「ぐへへお姉ちゃんパンツ何色」「ぐへへお姉ちゃん○色のパンツ履いて」と言って呼んでいるのです。
……ですが注意してください。oneechan::get_pants_color()が実際に何をするかまではわかりません。内部ではoneechan::call_police()と同じ処理をやっている可能性は高いとおもわれます。
また、oneechan::get_pants_color()を利用する際には
(2011/12/07追記)
nullptrはintに型変換されないのでコンパイルエラーになるとの指摘を受けました。しかしNULLだと0に変換されるので黒のパンツになってしまう……これもゆゆしき問題です!なんとかしなければ……次の記事までに理想的なお姉ちゃんクラスとパンツの色について考え直すことにします。
まとめです
・お姉ちゃんのパンツの色を表現するのに構造体を使ってはならない(お姉ちゃんは露出狂ではない)
・お姉ちゃんのパンツの色はスカートで隠されている(隠蔽!)
・基本的にお姉ちゃんの情報はprivate(public以外は隠蔽!)
・privateな情報でもお姉ちゃん本人はアクセスできる
・private変数にpublicなメソッドを使ってアクセスする
・関数やメソッドの名前だけで内部の処理を見積もってはならない
・お姉ちゃんは偉大。
・白銀朱音は俺の姉(ry
クラスの重要さはお姉ちゃんのパンツにあらわれていました。
以上!!!
面白かった! ちょっと自分のサイトにトラックバック風に書いてみました。http://www.flat7th.org/~keizo/wiki/?page=memo%2F20111206
返信削除私はsingletonにはすごく意味があると思います。
削除「ほとんど意味は無い」はちょっと大げさかなぁと。
「使う人が気を付ければ良い」という運用ベースでプログラムは
成り立ちませんからね。それが「保証されている」というのが
すごく大事な事じゃないですかね。仕様に書くかどうかではなくて。
パンツ自体もオブジェクトだと考えられますので、
返信削除class pants;
を定義して、oneechanオブジェクトのprivateメンバとして実装し隠蔽することにより、
pants.get_size();
や
pants.get_type();
が実装でき、パンツの履き替えやパンツのバージョンアップにも対応できる、より実用的なパンツが実現すると考えられます。
> if(homuhomu.pants.color = 0x000000){なんかかんか}
返信削除pants_colorがpants.colorになってます。
ありがとうございます。訂正しました。
返信削除どちらかというと構造体とクラスの違いと隠蔽の説明ってかんじですね。
返信削除しかしこれは参考になる。
お姉ちゃんとfriendなら自由に見られるのでしょうか?
返信削除setterについての突っ込みです。
返信削除ぐへへお姉ちゃんパンツ何色 私は黒は穿かない! - GeekなNooblog
http://d.hatena.ne.jp/sona-zip/20111206/p1
http://d.hatena.ne.jp/laplus-knsn/20111206/1323175234
返信削除JavaScript編書いてみたんですけど、問題あったら消しますのでご連絡ください!
二匹めのドジョウを狙うブロガー達が今必死になって他言語仕様かプロセス変えただけバージョン作ってんだろうなー
返信削除胸熱
りっちゃんかよw(ネタバレ
返信削除rubyバージョン見たいです。
返信削除この記事を見て、オブジェクト指向が手続き型より優れているポイントを1つはじめて知りました。
返信削除構造体は自由に読み書きできるが、隠蔽されたデータは自由に読み書きできないことがある。
しかしそれなら値を書き換える関数や、値を返す関数を作れば同じことなのでは・・・などと思ってしまいます。
今後も分かりやすい講座をよろしくお願いします。
この記事の本質ではない(C++の)技術的な指摘で申し訳ないですが2点ほど。
返信削除> int oneechan::get_pants_color()
getterは基本的にconst付けてください。
int oneechan::get_pants_color() const
> また、oneechan::get_pants_color()を利用する際にはnullptrが返ってくる可能性、つまり「履いてません」エラーが出てくる可能性もあるということに……
NULLならともかく、nullptrはintへの暗黙変換はできないので、nullptrを返そうとしたらコンパイルエラーです・・・。
ご指摘ありがとうございました。訂正しました。
返信削除