全局静态常量字符串赢得';无法初始化 > Ubuntu .< /P>上运行C++
在configuration.h文件中,我有以下内容(全局): 在我的configuration.cpp(顺便说一句,它是单例的,所以由配置的构造函数调用load configuration)中,我执行以下操作:全局静态常量字符串赢得';无法初始化 > Ubuntu .< /P>上运行C++,c++,C++,在configuration.h文件中,我有以下内容(全局): 在我的configuration.cpp(顺便说一句,它是单例的,所以由配置的构造函数调用load configuration)中,我执行以下操作: void Configuration::loadConfiguration() { cout<< "config file name " << APP_CONFIG_FILE_NAME.data(); load(); } 我看到成本字
void Configuration::loadConfiguration() {
cout<< "config file name " << APP_CONFIG_FILE_NAME.data();
load();
}
我看到成本字符串没有初始化(为空)。如果我用char*替换字符串,它将按我期望的顺序初始化
但是在另一个程序上,相同的类用于配置工作,所以我不知道问题出在哪里
还有一个问题,但不一样,因为它不是全局的。当然,它会被初始化。但是,它很可能是按照您不希望/预期的顺序初始化的 具体来说,它可能不是在您使用它的时候构建的,因为您在构建另一个全局文件时使用了它 不幸的是,您没有一个好的方法可移植地指定全局数据的初始化顺序。标准中没有定义多个文件之间的初始化顺序,尽管它可能是由工具链指定的。因此,使用另一个工具链更改编译或构建的顺序可能会导致不同的初始化顺序。有关详细信息,请搜索“静态初始化订单失败” 避免此问题的一种方法是在函数中声明静态数据:
const std::string& AppConfigFileName() {
static const std::string name("cfg");
return name;
}
虽然…我不明白为什么这必须是静态的(上面的函数允许您按值返回——不需要静态)。另外,我不明白为什么这不能是一个普通的C字符串,因为在配置加载器中将其视为一个C字符串。关键问题是调用
Configuration::loadConfiguration
时。这个
转换单元之间的初始化顺序未定义,因此
如果从的构造函数调用了Configuration::loadConfiguration
另一个转换单元中的静态对象,变量可能没有
已经建成。在这种特殊情况下,最简单的解决方案是
只需将类型更改为char const[]
;这允许静态
初始化,在任何动态初始化之前发生。(任何
涉及非平凡构造函数的初始化是动态的。)
更一般地说,可以对字符串使用单例模式
其他几点也值得一提:
- 您已经在头文件中声明了对象的
实例。 这意味着包括头文件的每个翻译单元 将有一个单独的对象实例。这可能不是个好主意 好主意静态
- 您可以输出
。这只是其中的数据APP\u CONFIG\u FILE\u NAME.data()
对象它是而不是std::string
结束。当需要以'\0'
结尾的字符串时,必须使用'\0'
。(但在这种情况下,您可以只输出std::string::c_str()
。不需要对其进行任何函数调用。)std::string
Timer t(Configuration::Instance()->timeout);
const std::string& AppConfigFileName() {
static const std::string name("cfg");
return name;
}