2012-09-18 6 views
6

可能な重複のプライベートメンバーにアクセスすることができます。
why private value of the obj can be changed by class instance?なぜ==のオーバーロードは、引数

は、以下の(部分)コード考えてみましょう:

class Group { 
    private: 
     int id; 

    public: 
     void set_id(int); 
     int get_id(); 
     bool operator==(const Group&); 
}; 


bool Group::operator==(const Group& g) { 
    if(g.id == this->id) { /* id is private? */ 
      return true; 
    } 

    return false; 
} 

コードをコンパイルして、結果は正しいようです。しかし、演算子オーバーロードの実装の一部であるifでは、引数-const Group& gのプライベートメンバーに直接アクセスしていますが、そのようなアクセスは無効ではありませんか?

+1

? – sbi

+1

補足として、ユーザー名「WeaklyTyped」はこの質問に非常によく似ていると思います。 – datenwolf

+1

@sbi - 不要な 'this->'があります。 –

答えて

16

operator==は、Groupクラスのメンバーです。メンバー関数は、thisだけでなく、アクセスできるすべてのインスタンスに対して、そのクラスのメンバーprivateにアクセスできます。

これは、オブジェクトが任意のメンバー変数へのパブリックアクセサを持っていない限り、アクセス制御が2つ以上のインスタンス(swap、コピーコンストラクタ、演算子)の対話のためのメソッドを不可能にするため、そのような方法で使用される。多くの場合、設計の観点から望ましくないほど十分です。さらに、アクセス制御のバーを高くする(「単に私がそのメンバーを公開すると、私は苦痛を払うことができます...」)。このコードを総括

は(ifは、単にreturn g.id == this->id;を使用する場合と比較して、必要な理由私が表示されていないが)完全に有効です

`リターンg.id == this-> id`と間違って何
+0

ありがとう!説明のために。 – WeaklyTyped

5

いいえ、operator==Groupのメンバーです。関数名のすぐそばにあります。つまり、そのクラスのののメンバーprivateにアクセスできます。

あなたがコンパイルしなかったであろうフリー機能、としてそれを書くためにしようとした場合:

bool areEqual(const Group& g1, const Group& g2) { 
    return g1.id == g2.id; 
} 
13

アクセス修飾子は、インスタンスレベルでアクセスを制御しますが、タイプレベルでされていません。 T型のインスタンスのメンバ関数は、同じ型の他のインスタンスのすべてのプライベートメンバにアクセスできます。

operator==はメンバ関数なので、クラスのインスタンスのすべてのメンバ変数にアクセスできますのメンバー。

+0

私はあなたの意見を得ていますが、なぜ指定子がインスタンスレベルではなくタイプレベルで動作するのかを指摘できたら本当に感謝しますか?理由があるはずです。 – WeaklyTyped

+1

@WeaklyTyped型レベルで動作しなかった場合は、すべてのデータが公開されていない限り、または単一のデータメンバーごとに「ゲッタ」が存在する場合を除いて、構造体または代入をコピーできません。 – juanchopanza

+0

@WeaklyTyped:C++は静的型チェック言語であり、アクセスがインスタンス内に残っているかどうかを静的に判断することはできません(問題の停止)。たとえば、メンバー関数 'class T {private:int bar; ' - fooは、クラスの外側またはクラスの内側から呼び出すことができます。' - foo()このポインタ。コンパイル時に、これが起こるかどうかを静的にチェックすることは不可能です。 juanchopanzaが言ったことも。 – datenwolf

関連する問題