Java风格的静态常量初始化
java style static constant initialization
我是一个c++新手。我试图在c++中创建一个静态常量容器。在java中,我们通常通过静态常量初始化来实现。例如
class ConstantDefinition {
public static const List<String> stringList = new ArrayList<String>();
static {
stringList.add("foo");
stringList.add("boo");
...blah
}
}
java的工作方式,我不需要调用一个特定的方法来完成初始化。静态块在类加载到JVM中时被初始化。但是在c++中,我们没有与java相同的类加载机制。我想要的是有一个不可修改容器的副本,我可以使用,而不必每次都创建类对象。我理解的一种方法是创建一个类(类似于上面的java示例)并定义一个const静态容器。但我发现在c++中编写这种代码很困难,因为我不能在不调用方法的情况下进行初始化。那么,实现这一目标的最佳方式是什么呢?第二种方法是定义头文件并在名称空间内初始化全局变量。如果我采取这种方法,那么它会创建不同的全局变量,每次当我包括头文件或相同的一个将被使用?
谢谢,RG
有几种解决方案,取决于操作的复杂程度实际初始化是多少,以及是否可以指望c++ 11或不是。在所有情况下,解决方案都取决于这样一个事实构造函数在静态变量上调用已加载执行
在最简单的情况下,您只需用an来定义变量初始化参数,例如:
在课堂上:
class ConstantDefinition
{
static std::vector<std::string> const stringList;
// ...
};
(对于所有的解都是一样的)
在源文件中:
std::vector<std::string> const ConstantDefinition::stringList{
"foo",
"boo",
// ...
}
这只适用于c++ 11。使用早期版本的在c++中,您需要定义变量:
std::string const stringListInit[] =
{
"foo",
"boo",
// ...
};
std::vector<std::string> const ConstantDefinition::stringList(
begin( stringListInit ), end( stringListInit ) );
您还需要函数begin
和end
:
template <typename T, size_t N>
T* begin( T (&array)[N} ) { return array; }
template <typename T, size_t N>
T* end( T (&array)[N] ) { return array + N; }
如果你没有c++ 11(它们在标准中)库),无论如何你都会需要它们。
不要忘记,在任何一个初始化列表中,你都可以使用任意表达式进行初始化,包括函数调用.
最后,如果您的初始化过于复杂,您可以始终将其封装在函数中:
namespace {
std::vector<std::string> stringListInit()
{
std::vector<std::string> results;
results.push_back( "foo" );
// ...
return results;
}
}
std::vector<std::string> const ConstantDefinition::stringList( stringListInit() );
不要太担心创建数组,它将是复制,然后销毁;c++允许NRVO,这意味着编译器实际上可以"合并"本地变量在stringListInit
和ConstantDefinition::stringList
,所以只有一个std::vector<std::string>
实际构建
如果将此代码放入任何编译单元(可能是源文件)
namespace {
static struct Initialiser
{
Initialiser()
{
// ToDo - initialisation code here
}
} TheInitialiser;
}
然后代码块将在加载库/可执行文件后运行(并且在调用main
函数之前)。这个成语很常见。
外部namespace{}
(称为匿名命名空间)块防止将此代码发送到链接器和其他编译单元中。
In ConstantDefinition.hpp:
#include <string>
#include <vector>
struct ConstantDefinition
{
static const std::vector<std::string> string_array;
};
In ConstantDefinition.cpp:
const std::vector<std::string> ConstantDefinition::string_array =
{
"foo",
"boo"
};
注意: c++ 11或更高要求。
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 如何使用数据对象上的常量指针初始化类
- 为什么C++常量模板化向量在使用之前没有初始化?
- 犰狳C++ - 从常量内存初始化只读矩阵而不复制
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- C++ 模板中的静态常量初始化顺序
- 具有静态存储持续时间的常量初始化变量的初始化顺序
- 当 T 具有非平凡析构函数时,类类型 T 的对象是否可以常量初始化?
- 对常量初始化的困惑
- 在不同翻译单元中具有静态存储持续时间的依赖非局部常量浮点变量的常量初始化
- 使用静态常量初始化unique_ptr时出现未定义的引用错误
- 正在从常量初始化字符数组
- 如果首先使用非常量初始化,为什么允许对 const 的非常量引用?
- 通过元编程自动+静态类内常量初始化
- 多个数据成员的常量初始化
- 使用整数常量0初始化实例,但不使用其他常数值或整数变量
- float的类内静态常量初始化与C++中的int有何不同
- 用常量初始化数组无效
- 在常量初始化器中调用constexpr构造函数的限制
- Java风格的静态常量初始化