2012-01-03 50 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是唯一的解決方案。另外,如果有更多派生模塊,那麼對於類型轉換,基本模塊類中需要一些智能。

+0

這種事情的用例場景是什麼?正如你可能(正確)認識到的那樣,如果你的基類需要知道派生類,那麼可能會有一個基本的設計問題。 – 2012-01-03 10:08:17

+0

用例如下所示 - Base代表系統,Base2代表系統中的模塊。我想概括一下系統和模塊的創建方式,以及這些模塊如何在系統和系統中彼此交互。因此,爲了使模塊相互作用的通用方式,它們必須是Base類的一部分。 – user1127533 2012-01-03 10:23:37

回答

0

如果DerivedBase的唯一具體實例,則可以使用static_cast代替。

就我個人而言,我定義了一個函數,如MyCast爲每個專門的類。我定義了四個重載的變體,以便我可以向下轉換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。

擁有全部四個優點的最大好處是你不會偶然改變const,並且無論你有指針還是引用,你都可以使用相同的構造。

當然,你可以用宏替換static_cast,並在調試模式下使用dynamic_caststatic_cast是釋放模式。

此外,上面的代碼可以很容易地包裝到一個宏中,使批量定義函數變得容易。

地使用這種模式,然後你可以實現你的代碼爲:

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

非常感謝,如果我們只有一個派生類,但是當我們有來自同一基類的多個派生類時,投射到特定的派生類需要一些存儲在基類中的智能。有沒有更好的方法來設計這樣一個系統,同時也避免了基類或者基礎指針中的智能? – user1127533 2012-01-03 11:54:26

0

設計變得乾淨多了,如果Base不包含base_obj對象,而是獲得通過虛擬方法的引用。 Derived應包含Derived2對象,如:

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構造函數傳遞引用。

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 2012-01-03 13:40:14

+0

我很困惑。我不明白這個問題。也許你應該重新發布你的代碼並給這些類指定完整的名字。確保它編譯。 – ScrollerBlaster 2012-01-03 13:46:17

+0

我無法對你的問題發表評論。沒有代表!難道你不能在其基類中虛擬module_alpha_function?爲什麼這種痛苦? – ScrollerBlaster 2012-01-03 14:37:14