2012-01-03 4 views
1

私は基本的な機能を提供し、他の派生システムのインターフェイスとして機能するはずのC++でフレームワークを設計しています。C++デザインクエリ

#include <stdio.h> 

class Module 
{ 
    public: 
    virtual void print() 
    { 
     printf("Inside print of Module\n"); 
    } 
}; 
class ModuleAlpha : public Module 
{ 
    public: 
    void print() 
    { 
     printf("Inside print of ModuleAlpha\n"); 
    } 
    void module_alpha_function() /* local function of this class */ 
    { 
     printf("Inside module_alpha_function\n"); 
    } 
}; 
class System 
{ 
    public: 
    virtual void create_module(){} 
    protected: 
    class Module * module_obj; 
}; 
class SystemAlpha: public System 
{ 
    public: 
    void create_module() 
    { 
     module_obj = new ModuleAlpha(); 
     module_obj->print(); // virtual function, so its fine. 

     /* to call module_alpha_function, dynamic_cast is required, 
     * Is this a good practice or there is some better way to design such a system */ 
     ModuleAlpha * module_alpha_obj = dynamic_cast<ModuleAlpha*>(module_obj); 
     module_alpha_obj->module_alpha_function(); 
    } 
}; 

main() 
{ 
    System * system_obj = new SystemAlpha(); 
    system_obj->create_module(); 
} 

コードをより論理的に編集し、すぐにコンパイルします。問題は、そのようなシステムを設計するための良い方法があるか、dynamic_castが唯一の解決策であるということです。また、より多くの派生モジュールがある場合は、型キャストのために、基本Moduleクラスにいくつかのインテリジェンスが必要です。

+0

この種の事例では、どのようなユースケースのシナリオがありますか?おそらく(正しく)実現したように、基底クラスに派生クラスの知識が必要な場合、基本的な設計上の問題があるかもしれません。 –

+0

ユースケースは次のようなものです。ベースはシステムを表し、ベース2はシステムのモジュールを表します。私は、システムとモジュールがどのように作成されるか、それらのモジュールがシステム内でどのように相互にやりとりするか、システム間で相互作用する方法を一般化したい。したがって、モジュールが相互作用する一般的な方法を作るためには、それらはBaseクラスの一部でなければなりません。 – user1127533

答えて

0

具体的な例がBaseの場合は、Derivedのみstatic_castを使用できます。

個人的には、すべての特殊なクラスに対してMyCastのような関数を定義します。私は4つのオーバーロードされたバリアントを定義するので、constポインタと非constポインタと参照をダウンキャストできます。例:

inline Derived  * MyCast(Base  * x) { return static_cast<Derived *>  (x); } 
    inline Derived const * MyCast(Base const * x) { return static_cast<Derived const *>(x); } 
    inline Derived  & MyCast(Base  & x) { return static_cast<Derived &>  (x); } 
    inline Derived const & MyCast(Base const & x) { return static_cast<Derived const &>(x); } 

同様に、Derived2とBase2についても同様です。

すべての4つを持つことの大きな利点は、あなたが意図せずにconstを変更しないことと、ポインターまたは参照を持っているかどうかにかかわらず同じ構造を使用できることです。

もちろん、static_castをマクロに置き換えて、dynamic_castをデバッグモードで使用し、static_castをリリースモードにすることができます。

また、上記のコードを簡単にマクロにラップすることで、関数をバッチ定義することが容易になります。 Basebase_objオブジェクトが含まれているのではなく、仮想メソッドを介して基準を取得していない場合は、デザインは非常にクリーン取得

class Derived : public Base 
{ 
public: 
    virtual void func2() 
    { 
    base2_obj = new Derived2(); 
    } 
    void DerivedFunc() 
    { 
    MyCast(base2_obj)->Derived2Func(); 
    } 
} 
+0

ありがとう、良い唯一の派生クラスがある場合、同じ基本クラスから複数の派生クラスがある場合、特定の派生クラスにキャストするには、基本クラスにいくつかのインテリジェンスが必要です。そのようなシステムを設計するための良い方法はありますか?また、基底クラスやキャストのベースポインターでそのインテリジェンスを回避する方法はありますか? – user1127533

0

:として、このパターンを使用して

、あなたは、あなたのコードを実装することができます。あなたは、パフォーマンスを心配している場合は、

class Base 
{ 
    public: 
     virtual void func1(); 
    private: 
     class Base2; 
     virtual Base2& get_base2(); 
}; 
class Derived : public Base 
{ 
     Derived2 derived2; 
    public: 
     Base2& get_base2() { return derived2; } 
     void DerivedFunc() 
     { 
       derived2->Derived2Func(); 
     } 
} 

Baseのコンストラクタで参照を渡す:Derivedは次のように、Derived2オブジェクトが含まれている必要があります。

0

私は多くのコンパイルエラーであなたのコードを取り、それを単純化しようとしました。これはあなたが達成しようとしていることですか?それはコンパイルされます。

class Base2 { 
    public: 
    virtual void Derived2Func(){ 
    } 
}; 

Base2* fnToInstantiateABase2(); 

class Base { 
    public: 
    Base() : base2_obj(fnToInstantiateABase2()) { 
    } 
    virtual void DerivedFunc() { 
    } 
    protected: 
    Base2* base2_obj; 
}; 
class Derived : public Base { 
    public: 
    void DerivedFunc() { 
     base2_obj->Derived2Func(); // not possible as base2_obj is of type Base2 
    } 
}; 


class Derived2 : public Base2 { 
    public: 
    void Derived2Func() { 
    } 
}; 


void test() { 
    Base * base_obj = new Derived(); 
    base_obj->DerivedFunc(); 
} 

Base2* fnToInstantiateABase2() { 
    return new Derived2(); 
} 
+0

投稿したプログラムは質問に答えません。 Derived2Funcは、Base2クラスの仮想関数ではなくDerived2クラスのローカル関数であるはずです。実際の問題は、Derived2クラスでインスタンス化されたBase2オブジェクトからDerived2Funcを呼び出す方法でした。 – user1127533

+0

私は混乱しています。私はその質問を理解していない。あなたのコードを再投稿し、クラスに意味のある名前を付けるべきでしょう。それがコンパイルすることを確認してください。 – ScrollerBlaster

+0

あなたの質問にはコメントできません。担当者がいない!基本クラスでmodule_alpha_functionを仮想にすることはできませんでしたか?なぜ苦しむ? – ScrollerBlaster