2

検討:

class A {
protected:
    int _i;
};

class B : public A {
    B(const B & object) {
        _i = object._i;
    };

    B(const A & object) {
        _i = object._i;
    };
};

パーミッションはオブジェクトではなくクラスに基づいているため、最初のコピーコンストラクターは正しいです。したがって、自分のクラスオブジェクトから保護されたメンバーに到達できます。2番目のコンストラクター(または同様のメソッド)でコンパイル時エラーが発生するのはなぜですか?

つまり、この場合、C ++でのアクセス許可チェックがクラス継承ルールを考慮しないのはなぜですか?

また、これはApple LLVM-4.2で発生しましたが、AppleLLVM-4.1では発生しませんでした。

4

1 に答える 1

3

要するに、この場合、C++ でのアクセス許可チェックがクラス継承規則を考慮しないのはなぜですか?

2 番目のコンストラクターを禁止するルールの背後にある理論的根拠を求めています。

理論的根拠を理解するには、次のコードを検討してください。

A a;
a._i = 100; //error, _i is protected 

それは正しく、期待されています。ここまでは順調ですね。

しかし 2 番目のコンストラクターが (コード内で) 許可されている場合、誰でもクラスmodifyを次のように記述できます。

struct modify : public A {
    void i(A & object, int newValue) {
        object._i = newValue; //MODIFY THE PROTECTED MEMBER of the argument!
    };
};

そして、代わりにこれを行うことができます:

A a;
modify().i(a, 100); //okay, indirectly modify a._i !!!
std::cout << a._i << std::endl; //prints 100

protected2 番目のコンストラクターが引数のメンバーにアクセスできる場合modify::i()は、同じことができます。そうすれば、保護されたメンバーを実際に変更できます。

于 2013-01-29T12:54:29.450 に答える