2014-10-06 79 views
0

這是怎麼回事: 問題是這樣的 - 爲了讓我的程序跨平臺,我爲操作系統執行的操作完成了一個抽象層。有一個抽象基類,稱爲SystemComponent這看起來是這樣的:如何將一個抽象類變成一個單例對象?

class SystemComponent{ 
public: 
    //some functions related to operations for OS 
    virtual WindowHandle CreateNewWindow(/*...*/) = 0; 
    virtual void Show_Message(/*...*/)   = 0; 
    //... 
} 

這然後通過另一個操作系統特定的類繼承的,比如說爲Windows的WindowsSystemComponent

#ifdef _WIN23 

class WindowsSystemComponent : SystemComponent{ 
public: 
    virtual WindowHandle CreateNewWindow(/*...*/); 
    virtual void Show_Message(/*...*/); 
    //... 
protected: 
    //Windows specific things... 
} 

#endif 

WindowsSystemComponent然後impliments的OS特定的功能。

在Windows中創建一個系統組件,我這樣做:

WindowsSytemComponent* pWSystemComp = new WindowSystemComponent(); 
//... 
//And the pass a pointer to this to the crossplatform code like this 
pFrameWork->SetSystem((SystemComponent*)pWSystemComp); 

,其中框架可通過在SystemComponent指定的OS功能的調用,並傳遞到任何子類需要它的指針。

需要什麼樣的: 我想刪除指針的傳球,使SystemComponent類和OS特定功能implimentations acsessible到想要使用它們每個對象。要做到這一點的最佳方法是使它成爲一個單身,但whin我嘗試做一些像

virtual static SystemComponent* Instance() { /*...*/ }; 

SystemComponent類,它是抽象的裏面,我得到一個編譯錯誤,說這樣的事情是不允許的。

那麼,我應該怎麼做呢?

+1

相關:http://stackoverflow.com/questions/22998019/template-singleton-base-class-in-shared-object/22998472#22998472 – 2014-10-06 16:35:41

回答

4

你不能有一個虛擬的靜態方法,但Instance方法不需要是虛擬的 - 它只需要爲你正在運行的平臺創建正確類型的SystemComponent。您只需要現在使用的代碼爲該平臺創建SystemComponent實例並將其放入Instance方法。

+0

但如果'WindowsSystemComponent'的存在也不是什麼已知的'SystemComponent'類? – 2014-10-06 16:41:57

+1

@TheLightSpark - 頭文件不需要知道平臺特定的組件,只有實現。你可以在特定於平臺的源文件中使用不同的實現(這是我想象你現在創建實例時所做的,除非你有平臺特定的框架初始化代碼) – antlersoft 2014-10-06 16:45:56

1

這不能按照您提出的方式完成。但是我認爲可以解決你的問題的是使用工廠模式。 Wikipedia

你可以做這樣的事情:

class SystemComponentFactory 
{ 
    static SystemComponent* ptr = 0; 

    static SystemComponent getSystemComponent() 
    { 
    if (ptr == 0) 
    { 
     if (isWindows()) 
      ptr = new WindowsSytemComponent(); 
     else if (isLinux()) 
      ptr = new XwindowsSystemComponent(); 
     ... 
    } 
    return ptr; 
    } 
}; 
1

你將不能夠實例化一個類,它是抽象的。 單例模式將類的實例化限制爲一個對象。這與先前的約束相沖突。您最好考慮使用abstract factory pattern

3

解決這個問題的另一種方法是模擬單例的概念,但讓派生類設置要使用的單例。

class SystemComponent 
{ 
    public: 
    static SystemComponent* instance() 
    { 
     return theInstance_; 
    } 

    //some functions related to operations for OS 
    virtual WindowHandle CreateNewWindow(/*...*/) = 0; 
    virtual void Show_Message(/*...*/)   = 0; 
    //... 

    protected: 

    static setInstance(SystemComponent* in) 
    { 
     theInstance = in; 
    } 
} 

// Define the static member. 
SystemComponent* SystemComponent::theInstance = nullptr; 

當使用WIN32,確保WindowsSytemComponent是獨立的,並在初始化時的基類設置的實例。

SystemComponent::setInstance(WindowsSytemComponent::instance()); 

當使用其他平臺時,請做類似的事情。

SystemComponent::setInstance(AnotherPlatformSytemComponent::instance());