2

これ以上のタイトルは考えられません...できれば編集してください!

class AbstractGUIBase
{
...
};
class GUIConcrete : public AbstractGUIBase
{
...
};

class AbstractApplicationBase
{
 AbstractGUIBase *mGUI;
};

class MyApplication : public AbstractApplicationBase
{
 GUIConcrete *mGUI;
};

これは基本的に私が持っているセットアップです...アプリケーション基本クラスは、GUI基本クラスインスタンスへの参照を含む一般的な機能を提供しますmGUI。または他の具体的なサブクラスmGUIでのみインスタンス化されます。MyApplication

mGUIのようなことをしてしまうので、両方のクラスで再宣言したくありませんsuper::mGUI = mGUI = new ConcreteGUI()mGUIただし、で使用するたびにキャストする必要はありませんMyApplication

ここに通常のパターンはありますか?GUIクラスタイプでテンプレート化できると思っていAbstractApplicationBaseましたが、テンプレートプログラミングは特に好きではありません。

私はMSVC++2008を使用しているので、最新のものはありません。

4

1 に答える 1

3

モデルの詳細を取り除き、次の抽象的なデザインに焦点を当てます。

                struct A                    struct DA : A 
                {                           {
                };                          };

//==============================================================================

                struct B                    struct DB : B 
                {                           { 
                    A* p;                       DA* pD; // Avoid this
                };                          };

ここで実行しようとしているのは、に余分なメンバー変数を追加しないようにし、から継承されDBたポインターをタイプのように処理できるようにすることです。pBDA*

クラスBを構造化することができ、次のDBようになります。

struct B
{
private:
    A* p;
public:
    B(A* _p) : p(_p) { }
    A* get_p() { return p; }
}

struct DB : B
{
public:
    B(DA* _p) : B(_p) { }
    DA* get_p() { return static_cast<DA*>(A::get_p()); }
}

スーパークラスBは、タイプのポインタを保持しますA*。このポインタは構築時に設定されます。のインスタンスの作成中にコンストラクターが呼び出されるとDB、タイプのオブジェクトへのポインターDAが格納されます。のバージョンを非表示にし、タイプの(適切にキャストされた)ポインタを返すDB関数get_p()を提供します。Bget_p()DA*

この設計により、static_cast<>inDB::get_p()は安全であることが保証されています(仮想継承を使用する場合を除きます。仮想継承を使用する場合は、効率の低いものを使用する必要がありますdynamic_cast<>)。

の内部操作はB、ポインタpに直接アクセスします。のクライアントはB、への呼び出しを通じてそれを取得しますB::get_p()。の内部DB、およびのクライアントの場合も、直接逆参照するのではなく、関数を介してポインタを取得することにより、が指すDBオブジェクトにアクセスします。pB::get_p()p

于 2013-02-13T17:39:47.550 に答える