2015-01-14 62 views
0

我的程序中有幾個模塊(例如數據庫,調度程序),它使用相同的實體 - 一些遊戲服務器。安全使用實體從程序的不同部分

主要目標是每個模塊使用具有有限功能的遊戲服務器API(僅需要在獨立模塊和遊戲服務器之間進行交互的功能)以及其他功能必須隱藏。

我已經創建了這樣的功能。但我現在不這樣做,也許這是錯誤的認識,或者也許有人會猜測更好的方法。

放置在下面的類包含一些只能通過類包裝器從其他模塊訪問的操作。

#ifndef _GAMESERVER_ 
#define _GAMESERVER_ 

#include <vector> 

class GameServer 
{ 
     static GameServer instance; 
     std::vector<int> game_actions; 
     GameServer(){} 
     ~GameServer(){} 
     GameServer(const GameServer&){} 

protected: 
     void addGameAction(int action) // Some functionality, which can be accessible  only from others modules via classes wrapers 
     { 
       game_actions.push_back(action); 
     } 

public: 
     static GameServer *getInstance() 
     { 
       return &instance; 
     } 
     bool start() 
     { 
       return true; 
     } 
     void stop() 
     { 
     } 
}; 
#endif 

下面放置了類GameServer的class'wrapper',它已經實現了與模塊Database交互的API。

#ifndef _DBGAMESERVER_ 
#define _DBGAMESERVER_ 

/* Database module will use this API for interacting with game server */ 

class GameServer; 

class DBGameServer : protected GameServer 
{ 
     DBGameServer(); 

public: 
     static DBGameServer *getInstance() 
     { 
       return static_cast<DBGameServer *>(GameServer::getInstance()); 
     } 
     void addGameAction(int action) 
     { 
       GameServer::addGameAction(action); 
     } 
}; 
#endif 

謝謝!

+0

'reinterpret_cast '應該是'static_cast'。但嚴重的是,對於我來說,完全不清楚你想用_wrapper_實現的目標。爲什麼不使用抽象接口,並將這些接口公開給應該使用它們的模塊? –

+0

'reinterpret_cast '很糟糕:'getInstance()'創建的對象是'GameServer',而不是'DBGameServer'。此外,還有一些潛在的錯誤:1)有人叫'stop()',之後有人使用單身人士; 2)getInstance不是線程安全的。 – Inspired

+0

什麼是你的問題? –

回答

0

您在第一次致電getIntance時創建了您的單例實例。它在多線程應用程序中可能不安全:競爭條件可能導致多個實例被初始化和使用。

恕我直言,你最好使用靜態初始化:

聲明:

... 
class GameServer { 
    static GameServer& instance; 
    // private constructor, copie constructor and destructor 
    ... 
public: 
    static GameServer * getInstance() { return &instance; } 
    ... 
} 

實現:

... 
GameServer & GameServer::instance = GameServer(); 
... 

這樣,你確信程序啓動過程中構造對象只有一次(在第一條指令之前),並且在程序結束時(在最後一條指令之後)調用析構函數。當然,如果構造函數拋出一個異常,程序會在它被給出任何顯示內容之前突然停止:最終的錯誤信息應該在構造函數中顯示。

+0

感謝您的回答! – scopichmu

相關問題