10

このコードがあるとしましょう

class A {
public:
    A() : x(1) {}
    virtual ~A() {}

    int x;
};

class B {
public:
    B() : y(2) {}
    virtual ~B() {}

    void g()
    {
        cout << "B::" << y << endl;
    }

    int y;
};

class C : private A, private B {
public:
    void f()
    {
        B* p = static_cast<B*>( this );
        p->g();
    }
};

int main()
{
    C c;
    ((B*)&c)->g();

    return 0;
}

static_castmain 関数の C スタイル キャストは、C++ キャスト ( 、dynamic_cast、 )では正しく表現できませんreinterpret_cast。しかし、そもそもこれを許可する理由は何ですか?カプセル化に害はありませんか?

更新 この質問はC++での設計上の決定に関するものであるため、これはリンクされた質問の複製ではありません。その言語で何ができるか、何ができないかではなく、特定の決定が下された理由を尋ねます。

4

3 に答える 3

8

ベース クラスと派生クラスへのポインター間で C スタイルのポインター キャストが使用されるとstatic_cast、ベースがプライベートであっても - のように動作します。

(関連のないポインター型間の C スタイルのキャストはreinterpret_casts です)。

規格は次のように述べています。

によって実行される変換

— const_cast (5.2.11)、

— static_cast (5.2.9)、

— static_cast の後に const_cast が続きます。

— reinterpret_cast (5.2.10)、または

— reinterpret_cast の後に const_cast が続きます。

明示的な型変換のキャスト表記を使用して実行できます。同じセマンティック制限と動作が適用されますが、次の状況で static_cast を実行すると、基底クラスがアクセス不能であっても変換が有効になるという例外があります。

— 派生クラス型のオブジェクトへのポインター、または派生クラス型の左辺値または右辺値は、明確な基本クラス型へのポインターまたは参照にそれぞれ明示的に変換できます。

— 派生クラス型のメンバーへのポインターは、明確な非仮想基本クラス型のメンバーへのポインターに明示的に変換できます。

— 明確な非仮想基本クラス型のオブジェクトへのポインター、明確な非仮想基本クラス型の glvalue、または明確な非仮想基本クラス型のメンバーへのポインターは、明示的にポインターに変換できます。それぞれ派生クラス型のメンバーへの参照またはポインター。

あなたの状況は最初のポイントで説明されているので、変換はによって行われstatic_cast、ポインターが調整されます。

于 2012-05-26T21:52:15.970 に答える
1

これは、C では、このキャストを使用して任意のポインターを他の任意のポインターに変換することが許可されており、C++ は可能な限り C と互換性を持たせようとしますが、クラスに関しては正しい仕事をしようとするため、C スタイルです。キャストはreinterpret_castこの状況よりも強力です。

于 2012-05-26T21:55:30.823 に答える
-1

C スタイルのキャストを使用すると、任意の型を他の任意の型に変換できます。必要に(std::istream*)&c応じて実行できますが、お勧めしません。

于 2012-05-26T21:52:35.377 に答える