强制静态成员初始化

时间:2011-11-01 16:27:31

标签: c++ initialization static-members

我有一个包含静态成员的类,一个函数指针的字符串映射。此映射旨在使用静态映射集填充一次,并且随后不会被修改。

我的问题是,如何在初始化之前确保不访问地图?我的代码目前看起来像这样:

class MyClass
{
  static MapType s_myMap;
public:
  static const MapType& getTheMap()
  {
    if (s_myMap.empty())
    {
      // Populate the map
    }
    return s_myMap;
  }
};

适用于MyClass的外部客户端,但不会阻止内部类成员在初始化之前直接访问private映射。

为了解决这个问题,我正在考虑将地图设置为getter方法的本地:

class MyClass
{
public:
  static const MapType& getTheMap()
  {
    static MapType s_myMap;
    if (s_myMap.empty())
    {
      // Populate the map
    }
    return s_myMap;
  }
};

这是一个好主意,还是有更好的方法来实现这个目标?

4 个答案:

答案 0 :(得分:1)

您可以为此集合声明一个类,并在构造函数中填充它。

答案 1 :(得分:1)

如果未在全局/ MyClass::getTheMap()范围内调用namespace,则您无需担心static数据成员在初始化之前使用。

但是,如果在全局/ static范围内使用上述getTheMap()方法namespace

SomeGlobal object = MyClass::getTheMap();

然后你现在的方法似乎很好。

答案 2 :(得分:1)

将静态移动到函数中将解决任何顺序 初始化问题,但它可能会给你一个订单 破坏一个。在许多情况下,最好使用指针和 动态分配,以便从不破坏地图。

至于初始化它,我经常使用两个迭代器构造函数,所以 我可以使地图本身成为常量。要做到这一点,只需定义一个 struct带有转换运算符,例如:

struct MapInitData
{
    char const* key;      //  Or whatever type is needed.
    char const* value;    //  Or whatever type is needed.
    operator MapType::value_type() const
    {
        return MapType::value_type( key, value );
    }
};

MapInitData const mapInitTable[] =
{
    { "key1", "value1" },
    //  ...
};

MapType const ourMap( begin( mapInitTable ), end( mapInitTable ) );

答案 3 :(得分:0)

你的函数'getTheMap'应该锁定它以保证线程安全。将它局部移动到函数是个好主意。

我认为这与drdobbs文章“C ++和双重锁定的危险”http://drdobbs.com/cpp/184405726有关,与问题类似。在这里,他介绍了不同类型的单例和安全的用例和安全性。其他具有线程安全性的模式。

就破坏而言,你需要摧毁它吗?