2011年3月17日木曜日

ちょっと気が楽になった

地震、そして原発と、関東在住ですがかなりびびってました。もう毎日毎夜ガクブルで、寝不足で…。
そしたら Twitter で、こんなのが回ってきました。


これ読んだら少し気が楽になりました。とりあえず、大丈夫そう。テレビとかだとひたすら不安感煽ることばっかりだし、ほんともうテレビとか二度と見ねえよっ。もともとほとんど見てないけど。

2011年3月5日土曜日

C++ クラスの private はどこまで private か?

先日、ふと気になった以下のようなコード:
class A
{
private :
    int a;

    class B
    {
    public :
        B( A* p )
        {
            p->a = 0;
        }
    };
};
何が問題かというと、class A の private メンバである変数「a」に対し、class B から public メンバのようにアクセスしているわけです。で、これが普通にコンパイルを通ってしまう。

必要があってできるかなと思ってやってみたらできたので、まあこれはこれで良かったのですが、これは C++ 標準の仕様なのか気になって調べてみました。そしたら海外の掲示板にて同じ疑問を持っていた仲間発見。結果を俺訳すると、
C++ Standard 11.8 入れ子のクラス
入れ子になったクラスは他のメンバと同じアクセス権を持ったメンバになります。このクラスを囲っているクラスは、入れ子になっているクラスに対して特別なアクセス権は持たず、通常のルールに従います。
とのこと。ちゃんと標準仕様だったわけですね。最初から C++ の仕様書読めよ、ってツッコミされそうですが(汗

まとめると次のような感じ:
class A
{
private :
    int a;

    class B
    {
    private :
        int b;

    public :
        B( A* p )
        {
            p->a = 0;    // OK
        }
    };

    void func( B* p )
    {
        p->b = 0;    // エラー
    }
};

つまり、クラス A の private メンバにアクセスして欲しくないクラスはクラス A の外に書けってことですね。今までクラス外で使用する必要のないものはクラス内に書く、というスタンスだったんですが、これを考えるとちょっと考え方を変える必要がありそうです。