3

以下の図は、この問題に対する 3 つの独立したテストを示しています。

(関数の定義ではなく、宣言に焦点を当てています ~~ )

http://i.stack.imgur.com/wYtA6.png

なぜ右の方が「 'A' is an inaccessible base of 'B' 」 というエラーになったのだろう。

g++ が派生クラスによってベースへの参照を初期化しているように見えるのはなぜですか (保護された継承によるエラーが発生します)。

真ん中のような変換演算子を使用して B を A に変換し、渡すのではなく (エラー 0、警告 0)。

写真の右側のコードは次のとおりです。

struct A {
    A &operator=( const A & ) { return *this;  }
}a;

struct B : protected A {
    operator A() {  return A();  };
}b;

int main( void )
{
    a = b;
    return 0;
}

助けてくれてありがとう!~

4

2 に答える 2

4

a = b;クラス内またはクラス外 (ワールド内) に書き込むとmain()、変換はクラス内ではなくそこで行われ、アクセシビリティ規則は変換ポイント (クラス外) で適用されます。このような変換を行うには、基底クラスが外部 (世界) からアクセスできる必要があります。

あなたの場合、はキーワードを使用してB派生しているため、世界は のサブオブジェクトにアクセスできないため、に変換できません。これはすべて、継承により( である)のベースがワールドからアクセスできないために発生します。やれやれ、世の中も回心するぞ。AprotectedAbBABAprotectedpublic

さて、この質問:

継承変換の代わりにユーザー変換関数を使用しないのはなぜですか?

継承変換はユーザー定義の変換関数よりも優先されるため、この優先設定を最初のステップと考えることができ、2 番目のステップは変換が失敗するアクセシビリティのルールと考えることができます。

于 2013-01-02T05:12:42.927 に答える
2

セクション 12.3.2:

変換関数は、(cv 修飾されている可能性がある) オブジェクトを (cv 修飾されている可能性がある) 同じオブジェクト型 (またはそれへの参照) に変換したり、その型の (cv 修飾されている可能性がある) 基本クラス (またはそれへの参照)、または (おそらく cv 修飾された) void への参照。

また、いくつかの例外を除いて、 // の選択によってpublic、プログラムが有効かどうかにかかわらず、プログラムの動作が変わることはめったにありませんprotectedprivateそのため、初期化では、ユーザー定義の変換を使用するのではなく、可能であればサブオブジェクトへの参照を直接バインドし、その選択が行われた後、コンパイラはアクセスをチェックします。

于 2013-01-02T05:16:37.670 に答える