2013-10-02 68 views
4

幾個月前,我創建了一個名爲Vexed的遊戲的C#項目。現在我正在創建一個俄羅斯方塊,但使用C++。基本上我想使用我在另一個項目中使用的相同邏輯,它有點像這樣:如何在C++中聲明一個類的靜態實例?

我創建了一個名爲「遊戲」的類,其中有關於遊戲的所有信息。它有方法,變量和一切。然後,我創建了一個名爲「PublicInstances」或類似的東西靜態類,並在I類中聲明是這樣的:

static class PublicInstances 
{ 
    public static Game vexedGame = new Game(); //This is C# and works. 
} 

這使得它使用起來非常簡單的話,因爲我在遊戲中的任何改變被保存在我班的靜態實例中,我可以在項目的任何地方訪問它。我想知道如何用C++做到這一點,創建我的類遊戲的公共或全局實例,以便我可以訪問它並在任何地方進行更改,並在我的項目的任何表單或類中更新所有內容。我將衷心感謝您的幫助。

//很抱歉,如果我的英語是不是最好的^^

+1

如果u真的想要一個全球性的,你不必須把它放在一個類中。只需將其聲明在頭文件中並在源文件中定義即可。但全局變量(或全局訪問靜態)通常是不好的設計 – Kal

+0

我的主要問題是我通常在窗體之間旅行,我需要從一個地方獲取信息到另一個地方,我如何更改全局變量或類的使用? – avatarbobo

+0

聽起來好像「TetrisGame」應該是一個命名空間,而不是一個對象。這也將消除爲其定義類類型的需要。 –

回答

3

修訂和總結

選項1

你可能只是聲明和定義遊戲對象的全局實例。 在頭文件中,例如game.h:

extern Game globalGameObj; 

當您在一個源文件game.h globalGameObj名稱變得可見。 您還需要創建一個實際的對象。在源文件中,例如game.cc(任何類外):

Game globalGameObj; 

訪問它由變量名:

globalGameObj.do_some_work(); 

選項2

使用一個通常被稱爲單例模式。以下內容添加到您的遊戲類(game.h):

class Game 
{ 
    public: 
    static Game &shared_instance() {static Game game; return game;} 

    private: 
    // Make constructor private. Only shared_instance() method will create an instance. 
    Game() {/*whatever initialisation you need*/} 
}; 

你跟shared_instance()方法獲得遊戲實例:

Game::shared_instance().go_some_work(); 

你沒有在上面使用任何喜歡你static class PublicInstances。 C++允許您引入一個名稱空間(例如PublicInstances)來提供名稱隔離並將全局對象保留在一個地方,但它可能會是一個矯枉過正的問題。無論如何,如果你的全局對象很少,那麼它很可能是一個糟糕的設計。

什麼選擇更好?有些人會認爲應該使用單身模式。它保證只創建一個實例。然而,選項1和選項2都有相同的問題:它們在代碼中引入了一個全局對象,其全部缺點歸因於全局變量。我會說這個單身人士是一個僞裝的全球對象。我沒有看到決定技術上的原因來支持這兩種選擇,所以我會說這是個人品味問題。

歷史註釋:)

我的選項2的第一個建議是使用動態分配的博弈對象,而不是一個函數的局部靜態對象。

static Game *instance() {if (!_inst) _inst = new Game(); return _inst;} 

很少有人認爲這不是最好的辦法了,謝謝KalargiopewebSimple。 C++ 03在線程出現時會初始化靜態對象。 C++ 11保證靜態初始化的安全。

C++ 11條草案,secion 6.7

such a variable is initialized the first time control passes through its declaration; 
such a variable is considered initialized upon the completion of its initialization. [...] 
If control enters the declaration concurrently while the variable is being initialized, 
the concurrent execution shall wait for completion of the initialization. 
+1

無需課程。 –

+1

你已經聲明瞭'S :: _inst',但你還沒有定義它。 – Adam

+0

也是一個更好的方法來做到這一點是'靜態S&instance(){static S inst;返回inst; }' – Kal

相關問題