用c ++填充静态成员容器

时间:2009-04-23 08:35:13

标签: c++ stl

我有一个静态类成员,它是一些容器,比如

(foo.h中)

class Foo
{
   ...
private:
   static list<string> s_List;
}

我需要使用许多特定值填充列表。实际上它也应该是 const ,但这可能会使问题进一步复杂化。 所有类成员函数都是静态的,因此在构造函数中初始化它是没有意义的。

6 个答案:

答案 0 :(得分:15)

一个常见的解决方案是做这样的事情:

// header
class Foo
{
...
private:
   static list<string> s_List;
}

// cpp
list<string> init()
{
     list<string> tmp;
     ... fill tmp with strings

     return tmp;
 }

 list<string> Foo::s_List(init());

另一种方法就像Neil Butterworth建议的那样。

答案 1 :(得分:8)

另一种方法是创建一个简单的初始化类:

list <string> Foo::s_List;

struct Init {
   Init() {
      Foo::s_List.insert("apple");
      Foo::s_List.insert("bannana");
      Foo::s_List.insert("grapes");
   }
};

static Init doInit;

请注意,由于列表是私有的,这可能需要您使Init成为Foo的朋友。将这些类包含在他们初始化的类中通常也很方便。

然而,我只是重新阅读你的问题而另一个想法发生 - 如果列表是const,你可能不会改变它,在这种情况下,一个简单的字符串数组,用排序顺序的字符串初始化可能是一个更好的解决搜索(使用std :: binary_search)肯定比列表更快,当然可以很容易地进行初始化。

答案 2 :(得分:4)

如果你的编译器支持C ++ 0x,那么这实际上是微不足道的。

#include <iostream>
#include <list>

class Foo
{
public:
   static std::list<std::string> s_List;
};

std::list<std::string> Foo::s_List = {"hello", "world", "asdf", "qwerty"};

int main()
{
    for(const std::string& str : Foo::s_List)
        std::cout << str << std::endl;

    return 0;
}

这适用于const和非const静态成员。我用clang-4.2,gcc-4.7,gcc-4.6和gcc-4.5测试了这个片段。 Gcc-4.5不支持更新的 for 语法,因此您必须使用传统的 for 循环和迭代器。另外,不要忘记将 -std = c ++ 0x 标志传递给编译器。我有理由相信Visual Studio也支持这一点,但我不确定并且不知道哪个版本。

答案 3 :(得分:1)

这取决于您需要在该列表中输入的值。它们是静态的还是需要某种形式的计算?

如果它们是静态的,您可以这样做:

namespace {
   const char* const initVals[] = { "A", "B", "C" };
}

list<string> Foo::s_list(initVals, initVals + 3);

答案 4 :(得分:0)

我(问题的​​作者)徒劳地尝试这样做的方式。


我试着像(在Foo.cpp中)那样做:

list<string> Foo::s_List = list<string>();
Foo::s_List.insert("apple");
Foo::s_List.insert("bannana");
Foo::s_List.insert("grapes");

但这会产生编译错误。


然后我想到了一个Initialize()方法并从代码中调用它

void Foo::Initialize()
{
    s_List.insert("rats");
    s_List.insert("cats");
}

Foo::Initialize(); 

//错误:编译器认为它是方法的重新授权,而不是调用。


唯一可行的想法(尚未尝试)将检查列表在每个使用它的方法中是否为空,如果是这种情况,请调用Initialize()。但那太丑了!

答案 5 :(得分:0)

一种可能的解决方案是使用一个访问器方法来检查它是否已初始化,如果不是,则执行此操作。