3

次の例のstatic_castで、「エラー:「A」は「B」のアクセスできないベースです」というメッセージが表示されます。

template<typename Derived>
class A {
protected:
    void funA() { static_cast<Derived *> (this)->funB(); }
};

class B: protected A<B> {
public:
    void funB() {}
    void funC() { funA(); }
};

int main() {
    B().funC();
    return 0;
}

ただし、代わりにreinterpret_castまたはCスタイルの型キャスト((Derived *)this)-> funB()を使用すると、コンパイル/動作します。この動作は正しいですか?

使用したコンパイラ:gccバージョン4.5.1 20100924(Red Hat 4.5.1-4)(GCC)。

ありがとう。

4

3 に答える 3

2

static_cast次の例では、「エラー: 'A' は 'B' のアクセスできないベースです」というメッセージが表示されます。

これは予想されます:Bは から派生してA<B>いますが、この継承は保護されています:Bおよびその派生クラスのみBが から派生したという事実を使用できますA<B>

reinterpret_castただし、代わりに (...)を使用すると、コンパイル/正常に動作します。この動作は正しいですか?

これは予想どおりです:reinterpret_castは継承や型間のその他の関係を気にしません。

可能であればreinterpret_cast、元のポインター値と同じ値 (同じバイトを指す) を持つポインターを与えるだけです。

これは単に問題を隠しているだけです。

ただし、代わりに (...) C スタイルの型キャストを使用すると、コンパイル/正常に動作します((Derived *)this)->funB()。この動作は正しいですか?

これは当然のことです。C スタイルのキャストはアクセス制御を無視します。これは単に問題を隠しているだけです。

修正は、と の間の継承関係をA<B>B、使用したい場所でアクセスできるようにすることです

于 2011-12-19T06:08:31.573 に答える
1

はい、そうです。protected継承があり、またはA<B>から派生していないため、の基本クラスを見て、が有効であることを伝えることができません。friendBBstatic_cast

于 2011-12-17T23:27:09.110 に答える
1

保護されたプライベート継承は、クラスまたはそのフレンドの外部で行うために必要な、クラス間関係を作成しません。static_cast基本的に、private/protected 継承は実装の継承であり、インターフェイスの継承ではありません。static_castそれが機能しない理由です。

于 2011-12-17T23:35:20.430 に答える