这是否解决了静态初始化顺序的惨败?

问题描述 投票:0回答:1

我们只说一个静态变量,一个在程序启动时自动添加内容的向量。这是有问题的,因为在向量初始化之前,任何时候都可能会在该向量上调用 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 擦除指针地址,对吗?所以这并不能解决问题。

我知道常见的方法是将向量作为静态变量放置在函数内,但这会在每次访问向量时产生一个分支,以检查它是否已初始化。

c++ static-initialization
1个回答
0
投票

你可以在另一个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++; }
    
© www.soinside.com 2019 - 2024. All rights reserved.