C ++初始化类中的静态variables?
我注意到我的一些函数实际上并没有访问这个对象,所以我把它们变成static
。 然后,编译器告诉我,他们访问的所有variables也必须是静态的 – 到目前为止,这是可以理解的。 我有一堆stringvariables如
string RE_ANY = "([^\\n]*)"; string RE_ANY_RELUCTANT = "([^\\n]*?)";
等等。 然后我使它们都是static const
因为它们永远不会改变。 但是,我的程序只编译,如果我把它们从类中移出:否则,MSVC ++ 2010抱怨“只有静态常量积分variables可能在一个类中初始化”。
那很不幸。 有没有解决方法? 我想把他们留在他们所属的class级里面。
它们不能在类中初始化,但可以在类之外的源文件中初始化:
// inside the class class Thing { static string RE_ANY; static string RE_ANY_RELUCTANT; }; // in the source file string Thing::RE_ANY = "([^\\n]*)"; string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)";
更新
我刚刚注意到你的问题的第一行 – 你不想让这些函数成为static
,你想让它们成为const
。 使它们成为static
意味着它们不再与一个对象相关联(所以它们不能访问任何非静态成员),并且使数据静态意味着它将与所有这种types的对象共享。 这可能不是你想要的。 使它们成为const
就意味着它们不能修改任何成员,但仍然可以访问它们。
迈克西摩给了你正确的答案,但要增加…
C ++可以让你在你的类体中声明和定义静态常量types ,正如编译器告诉的那样。 所以你可以这样做:
class Foo { static const int someInt = 1; static const short someShort = 2; // etc. };
而且你不能用其他types来做,在这种情况下,你应该在.cpp文件中定义它们。
静态成员variables必须在类中声明,然后在其外部定义!
没有解决方法,只需将其实际定义放在源文件中。
从你的描述中,它闻起来像你没有正确使用静态variables。 如果他们从来没有改变,你应该使用常量variables,但你的描述太泛泛,不能说更多的东西。
静态成员variables对于你的类的任何实例总是保持相同的值:如果你改变一个对象的静态variables,它也会改变其他所有的对象(事实上,你也可以在没有类的实例的情况下访问它们 – 即:一个对象)。
由于C ++ 11可以在一个类中使用constexpr
来完成。
class stat { public: // init inside class static constexpr double inlineStaticVar = 22; };
该variables现在可以通过以下方式访问:
stat::inlineStaticVar
我觉得值得一提的是,一个静态variables和一个常量variables是不一样的。
在一个类中使用一个常量variables
struct Foo{ const int a; Foo(int b) : a(b){} }
我们会像这样宣布
fooA = new Foo(5); fooB = new Foo(10); // fooA.a = 5; // fooB.a = 10;
对于一个静态variables
struct Bar{ static int a; Foo(int b){ a = b; } } Bar::a = 0; // set value for a
这是使用像这样
barA = new Bar(5); barB = new Bar(10); // barA.a = 10; // barB.a = 10; // Bar::a = 10;
你看这里发生了什么事。 与Foo的每个实例一起实例化的常量variables(如Foo实例)对于Foo的每个实例都有一个单独的值,并且根本不能由Foo进行更改。
和Bar一样,Bar :: a只有一个值,不pipeBar有多less个实例。 他们都分享这个价值,你也可以通过他们的任何实例来访问它。 静态variables也遵守public / private的规则,所以你可以让Bar只能读取Bar :: a的值。
只是添加其他答案的顶部。 为了初始化一个复杂的静态成员 ,你可以这样做:
像往常一样声明静态成员。
// myClass.h class myClass { static complexClass s_complex; //... };
做一个小函数来初始化你的类,如果这不是微不足道的。 这将被称为只是静态成员初始化的一次。 (请注意complexClass的复制构造函数将被使用,所以它应该被很好地定义)。
//class.cpp #include myClass.h complexClass initFunction() { complexClass c; c.add(...); c.compute(...); c.sort(...); // Etc. return c; } complexClass myClass::s_complex = initFunction();
如果你的目标是在你的头文件中初始化静态variables(而不是* .cpp文件,如果你坚持使用“header only”的话,你可能会需要这个文件),那么你可以通过使用模板。 模板化静态variables可以在标题中初始化,而不会导致定义多个符号。
看这里的一个例子:
类模板中的静态成员初始化
或者,将所有常量移到.cpp文件中,而不用在.h文件中声明。 使用匿名命名空间使它们在cpp模块之外不可见。
// MyClass.cpp #include "MyClass.h" // anonymous namespace namespace { string RE_ANY = "([^\\n]*)"; string RE_ANY_RELUCTANT = "([^\\n]*?)"; } // member function (static or not) bool MyClass::foo() { // logic that uses constants return RE_ANY_RELUCTANT.size() > 0; }