假设我在一个傍晚非常无聊,在经常盯着电脑显示器几个小时之后,我决定实施一个聚合C ++类来管理绘制像素的颜色,因为我显然已经疯了。对于初学者,我们只是告诉(可能是单身)ColorManager对象我们想要使用的颜色,它将返回一个Color对象,无论可能是什么。一个简单的实现如下:
#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);
应该让我们真的很容易做任何你需要Color对象的废话。
问题是你需要在某处初始化静态私有ColorMap,以便每个COLOR枚举对应一个正确的Color对象,VC ++ 2010似乎不喜欢你尝试的任何东西。所以问题是,我如何以及在何处初始化这张地图?
显然,这是一个人为的例子,但除此之外,或许为一个作为单身的类定义静态变量并不值得。或者,也许,我可能只是在getColor()中声明变量static,因为这是使用它的唯一函数,并且只是在第一次调用函数时产生开销(尽管对于这个简单的例子,这并不是更好)而不只是在那里放一个巨大的开关声明)。无论如何,我都很感激反馈。
答案 0 :(得分:14)
#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 :(得分:6)
使用静态方法创建初始化地图:
ColorManager::colorMap(ColorManager::makeColorMap());
其中makeColorMap
是以下静态方法:
ColorManager::ColorMap ColorManager::makeColorMap()
{
ColorMap retval;
retval[...] = ...;
retval[...] = ...;
...
return retval;
}
答案 2 :(得分:6)
std :: map有一个构造函数,它将一对迭代器作为参数,因此您可以使用例如一对数组初始化映射:
#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(...)},
...});
答案 3 :(得分:1)
一种选择是使用正确初始化地图内容的构造函数将ColorMap
从typedef
更改为自己的自定义类型。这样,当您静态初始化ColorMap
时,构造函数将使用正确的数据填充它,并且尝试使用ColorManager
的任何操作都将看到正确配置的ColorMap
。
答案 4 :(得分:1)
你可以这样做而不需要上课:
Color getColor(COLOR color)
{
static std::map<COLOR, Color> colorMap;
if(colorMap.empty()) // Only runs once.
{
colorMap[BLUE] = Color();
// ... etc ...
}
return colorMap[color];
}
答案 5 :(得分:-2)
您在.cpp中将其初始化为
ColorManager::ColorMap ColorManager::colorMap;
并在ColorManager
构造函数中创建Color
的所有实例并填充。