我已经阅读了很多关于c ++中静态类变量初始化的内容,而谷歌编码标准说只创建普通旧数据的静态(即原语和指针),我在网上看到了很多例子。作者违反该指南的书籍。
我还读过,只要你将静态保存在一个编译单元中,就不太可能遇到未定义的初始化问题。
好的...所以说...我想要一些专家意见,我是否会遇到一些问题,看起来像......
//header file snippet
struct TheStruct {
string theString;
string theString2;
float theFloat;
};
class TheClass {
public:
static const TheStruct Dude;
static const TheStruct Blah;
static const TheStruct TheStructArray[];
TheClass();
virtual ~TheClass();
TheStruct getCurrent();
private:
TheStruct current;
}
//impl file snippet
const TheStruct TheClass::Dude = { "Dude", "Dude", 0 };
const TheStruct TheClass::Blah = { "Blah", "Blah", 0 };
const TheStruct TheClass::TheStructArray[] = {TheClass::Dude, TheClass::Blah};
TheClass::TheClass() : current(TheClass::Dude) {}
TheClass::~TheClass() {}
TheStruct TheClass::getCurrent() {return current;}
我认为getCurrent()
方法没问题。静态const Dude
和Blah
包含在静态数组TheStructArray
中,以便将来使用。但是,我猜我仍然会遇到阵列的问题,如果它被其他一些类使用的话?例如,GUI可以使用该数组来提供可供选择的有效选项。
我来自Java背景,因此我经常使用private static final
来定义一些有效的“状态”......
谢谢!
答案 0 :(得分:3)
//impl file snippet
const TheStruct TheClass::Dude = { "Dude", "Dude", 0 };
const TheStruct TheClass::Blah = { "Blah", "Blah", 0 };
const TheStruct TheClass::TheStructArray[] = {TheClass::Dude, TheClass::Blah};
只要这三行按顺序编写,代码就没有问题,因为它们按照上述顺序初始化,因此您不会遇到 static initialization order fiasco。否则,您应该通过this link了解您可能遇到的问题以及您必须提供的solution。
答案 1 :(得分:1)
可能可能会出现问题
TheClass::TheClass() : current(TheClass::Dude) {}
IF并且仅当您在代码中的不同cpp中声明了静态或全局TheClass时。例如:
// somewhereelse.h
#include "TheClass.h"
class OtherClass {
static TheClass myTheClass;
}
// somewhereelse.cpp
TheClass OtherClass::myTheClass;
初始化“OtherClass :: myTheClass”对象(调用构造函数并访问TheClass :: Dude)可能会在TheClass :: Dude初始化其值之前发生。因此,您可能会在OtherClass :: myTheClass的构造函数中获得随机垃圾(或更糟糕的崩溃)。
这可以通过使用不同复杂度的c ++单例模式(取决于您的要求)来避免这种情况。
struct TheStruct {
string theString;
string theString2;
float theFloat;
};
class TheClass {
public:
static const TheStruct &Dude();
static const TheStruct &Blah();
static const TheStruct *TheStructArray();
TheClass();
virtual ~TheClass();
TheStruct getCurrent();
private:
TheStruct current;
};
//impl file snippet
const TheStruct &TheClass::Dude() {
static TheStruct DudeStruct = { "Dude", "Dude", 0 };
return DudeStruct;
}
const TheStruct &TheClass::Blah() {
static TheStruct BlahStruct = { "Blah", "Blah", 0 };
return BlahStruct;
}
const TheStruct *TheClass::TheStructArray() {
static TheStruct singletonStructArray[] = {TheClass::Dude(), TheClass::Blah()};
return singletonStructArray;
}
TheClass::TheClass() : current(TheClass::Dude()) {}
TheClass::~TheClass() {}
TheStruct TheClass::getCurrent() {return current;}
现在,无论在其他地方如何使用TheClass,初始化都不会被定义。如果OtherClass有一个静态的TheClass对象,即使它在其他任何东西之前被初始化,DudeStruct也会及时初始化为“current”的复制构造函数。