0

私はpimplイディオムを使おうとしています。特に、実装クラスは別のインターフェースを実装します。

// public_class.h
class PublicClass
{
public:
    /* public interfaces here */
private:
    class _PublicClass_impl;
    friend class _PublicClass_impl;
protected:
    _PublicClass_impl * const _impl;
};

// public_class.cpp
class PublicClass::_PublicClass_impl : public SomeInterface
{
    friend class PublicClass;
    /* all sort of stuff ... */
};

私の質問は、次の状況でどのキャストを使用できるかということです。

// some_other_class.h
class SomeOtherClass : private PublicClass
{
    void some_function()
    {
        // definition of _PublicClass_impl is unknown
        // thus, _impl is opaque

        SomeInterface * interface = dynamic_cast<SomeInterface *>(_impl); //??
        /* more code ... */
     }
};

この場合、dynamic_castは正常に機能しますか?この場合に使用できるキャストの他のタイプはありますか?

4

2 に答える 2

1

私が間違っていなければ、明示的なキャストはまったく必要ありません.SomeInterface_PublicClass_impl

私は実際に GCC (4.5.1) を使用せずにdynamic_castコードをコンパイルしようとしましたが、実際にはエラーや警告はありません (SomeInterface空のクラスとして定義しました)。

ただし、関連する 1 つの質問に興味をそそられました。問題の時点​​で後者が不透明であるにもかかわらず、コンパイラSomeInterfaceは が実際には の基本クラスであるという事実を考慮に入れるのはなぜですか?_PublicClass_impl

これについての説明に最も近いのは、C++ 標準の §11.2、第 5 節です。

基底クラスにアクセスできる場合、派生クラスへのポインターをその基底クラスへのポインターに暗黙的に変換できます (4.10、4.11)。

それにもかかわらず、何らかの理由で明示的なキャストを使用したい場合は、単純な静的キャストで問題ありません。

SomeInterface *interface = static_cast<SomeInterface *>(_impl);
于 2012-04-15T02:58:32.683 に答える
1

私が知る限り、あなたが望むことを保証する方法はありません。reinterpret_cast または c-style キャストは機能する可能性があります (動作は未規定です) が、他のものは、コンパイルできる場合はすべて未定義の動作です。

n3242 の 5.2.7.2 (公式の標準ではないことはわかっていますが、それに近いはずです) は、dynamic_cast(v) について次のように述べています。

T がポインター型の場合、v は完全なクラス型へのポインターの prvalue であり、結果は型 T の prvalue になります。T が左辺値参照型の場合、v は完全なクラス型の左辺値である必要があります。結果は、T によって参照される型の左辺値です。T が右辺値参照型である場合、v は完全なクラス型を持つ式であり、結果は T によって参照される型の xvalue です。

したがって、dynamic_cast は機能しません。

2 つの型の間に有効な変換が定義されていないため、static_cast は機能しません。

5.2.10.7 は reinterpret_cast(v) について述べています。

オブジェクトへのポインターは、別のオブジェクト型へのポインターに明示的に変換できます。 )) T1 と T2 の両方が標準レイアウト タイプ (3.9) であり、T2 の配置要件が T1 の配置要件よりも厳密でない場合。「T1 へのポインター」型の prvalue を「T2 へのポインター」型 (T1 と T2 はオブジェクト型であり、T2 のアラインメント要件は T1 のアラインメント要件より厳密ではない) に変換し、元の型に戻すと、元の型が生成されます。ポインター値。他のそのようなポインタ変換の結果は規定されていません。

したがって、 reinterpret_cast が機能する可能性があります。

最後に、コンパイラは型間の関係を認識していないため、キャストを使用しないと機能しません。

于 2012-04-15T03:44:39.850 に答える