我们只说一个静态变量,一个在程序启动时自动添加内容的向量。这是有问题的,因为在向量初始化之前,任何时候都可能会在该向量上调用 Push_back:
inline std::vector<const char*> my_vector;
int register_type(const char* name)
{
static int id_counter = 0;
my_vector.push_back(name);
return id_counter++;
}
内联 int my_type_1 = register_type("my_type_1");
虽然从技术上讲这没问题,因为内联静态变量根据标准保证按其出现顺序初始化,但这通常可能是一个坏主意,尤其是因为如果我从另一个调用寄存器类型,则不会给出这种保证头文件或 cpp 文件。所以我想如果我将向量转换为指向尚未初始化的向量的指针会怎样:
static inline std::unique_ptr<std::vector<const char*>> p_to_types;
int register_type(const char* name)
{
static bool bHasBeenInitialised = false;
static int id_counter = 0;
if (!bHasBeenInitialised)
{
p_to_types = std::make_unique<std::vector<const char*>>();
bHasBeenInitialised = true;
}
p_to_types->push_back(name);
return id_counter++;
}
inline int my_type_1 = register_type("my_type_1");
现在向量将在第一次使用之前被初始化,这就是我们想要的。但是,程序仍然有初始化 unique_pointer 的指令,如果在我初始化向量之后发生这种情况,则在构造 unique_ptr 时将用 null 擦除指针地址,对吗?所以这并不能解决问题。
我知道常见的方法是将向量作为静态变量放置在函数内,但这会在每次访问向量时产生一个分支,以检查它是否已初始化。
你可以在另一个cpp文件中定义一个惰性静态单例
std::vector<const char*>& getMyVector() {
static std::vector<const char*> vec;
return vec;
}
并在注册函数中使用 getMyVector()
int register_type(const char* name)
{
static int id_counter = 0;
getMyVector().push_back(name);
return id_counter++;
}