2011-06-02 62 views
14

讓我們說,我很無聊一個晚上,在經過幾秒鐘的盯着計算機監視器後,我決定實現一個聚合C++類來管理繪製像素的顏色,因爲我顯然已經瘋了。對於初學者來說,我們只需告訴(可能是singleton)ColorManager對象我們想要使用什麼顏色,並且它會返回一個Color對象,不管它是什麼。一個簡單的FPGA實現如下:C++初始化一個靜態地圖作爲一個私人類成員

#include "Color.h" 
#include <map> 

enum COLOR { RED = 0, BLUE, GREEN, YELLOW, ORANGE, WHITE, BLACK, 
    BRICKS_FROM_A_DISTANCE_ON_AN_UNUSUALLY_SUNNY_AFTERNOON, 
    // etc 
    COLOR_COUNT }; 

class ColorManager 
{ 
public: 
    ColorManager(); 
    ~ColorManager(); 
    Color getColor(COLOR color) const; 
private: 
    typedef std::map<COLOR, Color> ColorMap; 
    static ColorMap colorMap; 
}; 

所以,我希望,這個簡單的代碼:

ColorManger colorManager; 
Color blue = colorManager.getColor(BLUE); 

應該使它真正方便我們做任何廢話,你會需要顏色的對象。

問題是,您需要初始化您的靜態私有ColorMap,以便每個COLOR枚舉對應一個適當的Color對象,並且VC++ 2010似乎不喜歡您嘗試的任何內容。所以問題是,我如何以及在哪裏初始化這張地圖?

顯然,這是一個人爲的例子,但除此之外,也許爲一個類作爲單例函數定義靜態變量是不值得的。或者,也許我只需在getColor()中聲明變量static,因爲這是唯一使用它的函數,並且在第一次調用函數時會產生開銷(儘管對於這個簡單的例子來說,而不僅僅是在那裏放置一個巨大的開關語句)。無論如何,我欣賞這些反饋。

回答

12
#include <map> 
#include "Color.h" 

enum COLOR 
{ 
    RED = 0, BLUE, GREEN, YELLOW, ORANGE, WHITE, BLACK, 
    BRICKS_FROM_A_DISTANCE_ON_AN_UNUSUALLY_SUNNY_AFTERNOON, 
    // etc 
    COLOR_COUNT 
}; 

class ColorManager 
{ 
    typedef std::map<COLOR, Color> ColorMap; 

public: 
    ColorManager(); 
    Color getColor(COLOR color) const; 

private: 
    static ColorMap createColorMap(); 
    static ColorMap colorMap; 
}; 

// in some .cpp file: 

ColorManager::ColorMap ColorManager::createColorMap() 
{ 
    ColorMap ret; 
    // populate ret 
    return ret; 
} 

ColorManager::ColorMap ColorManager::colorMap = ColorManager::createColorMap(); 

或用C++ 11:

#include <map> 
#include "Color.h" 

enum COLOR 
{ 
    RED = 0, BLUE, GREEN, YELLOW, ORANGE, WHITE, BLACK, 
    BRICKS_FROM_A_DISTANCE_ON_AN_UNUSUALLY_SUNNY_AFTERNOON, 
    // etc 
    COLOR_COUNT 
}; 

class ColorManager 
{ 
    using ColorMap = std::map<COLOR, Color>; 

public: 
    ColorManager(); 
    Color getColor(COLOR color) const; 

private: 
    static ColorMap colorMap; 
}; 

// in some .cpp file: 

ColorManager::ColorMap ColorManager::colorMap = [] 
{ 
    ColorMap ret; 
    // populate ret 
    return ret; 
}(); 
1

一種選擇是將ColorMaptypedef更改爲具有正確初始化地圖內容的構造函數的自定義類型。這樣,當您靜態初始化ColorMap時,構造函數將填充正確的數據,任何嘗試使用ColorManager的操作都將看到正確配置的ColorMap

-2

你在的.cpp初始化,如

ColorManager::ColorMap ColorManager::colorMap; 

,並在ColorManager構造函數創建的Color所有實例,並填滿它。

+0

在VS2010,這將導致運行時內存訪問衝突中的XTree,想必當值類的構造函數分配。它雖然編譯。 – Shaun 2011-06-02 19:57:09

+0

@SHaun顯然你在構造函數中做錯了什麼......當心不要依賴於其他靜態變量。 – littleadv 2013-11-15 08:15:31

1

你可以像下面這樣做,而不需要一類:

Color getColor(COLOR color) 
{ 
     static std::map<COLOR, Color> colorMap; 
     if(colorMap.empty()) // Only runs once. 
     { 
      colorMap[BLUE] = Color(); 
      // ... etc ... 
     } 

     return colorMap[color]; 
} 
+0

確實,我在我的問題中提到過這個方法。然而,ColorManager是一個更大,更復雜的類的模擬,功能更多,所以我不想擺脫它。 – Shaun 2011-06-02 19:58:48

6

使用它創建一個初始化的地圖的靜態方法:

ColorManager::colorMap(ColorManager::makeColorMap()); 

其中makeColorMap如下靜態方法:

ColorManager::ColorMap ColorManager::makeColorMap() 
{ 
    ColorMap retval; 
    retval[...] = ...; 
    retval[...] = ...; 
    ... 

    return retval; 
} 
+0

我將ildjarn的答案標記爲已接受,但這是同一時間給出的同一個解決方案,所以upvoted。 – Shaun 2011-06-02 20:05:53

+0

謝謝!我注意到我們同時提交了類似的解決方案。 – 2011-06-02 20:08:35

6

的std ::映射具有一個構造函數的一對迭代器作爲參數的,所以你可以初始化與地圖,例如,對一個陣列:

#include "Color.h" 

#include <map> 

enum COLOR { RED = 0, BLUE, GREEN, YELLOW, ORANGE, WHITE, BLACK, 
    BRICKS_FROM_A_DISTANCE_ON_AN_UNUSUALLY_SUNNY_AFTERNOON, 
    // etc 
    COLOR_COUNT }; 

class ColorManager 
{ 
public: 
    ColorManager(); 
    ~ColorManager(); 
    Color getColor(COLOR color) const; 
private: 
    typedef std::map<COLOR, Color> ColorMap; 
    static ColorMap colorMap; 
}; 

using std::make_pair; 
using std::pair; 

std::pair<COLOR, Color> colorPairs[] = {make_pair(RED, Color(...)), 
             make_pair(BLUE, Color(...)), 
             make_pair(GREEN, Color(...)), 
             ...}; 

ColorManager::ColorMap ColorManager::colorMap(colorPairs, colorPairs + COLOR_COUNT); 

在C++ 0x中,你就可以簡單地這樣做:

ColorManager::ColorMap ColorManager::colorMap({{RED, Color(...)}, 
               {BLUE, Color(...)}, 
               {GREEN, Color(...)}, 
               ...}); 
相關問題