我有一个静态类成员,它是一些容器,比如
(foo.h中)
class Foo
{
...
private:
static list<string> s_List;
}
我需要使用许多特定值填充列表。实际上它也应该是 const ,但这可能会使问题进一步复杂化。 所有类成员函数都是静态的,因此在构造函数中初始化它是没有意义的。
答案 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)
一种可能的解决方案是使用一个访问器方法来检查它是否已初始化,如果不是,则执行此操作。