gpt4 book ai didi

c++ - 通过调用 C++ 中的静态类函数初始化的全局静态变量

转载 作者:行者123 更新时间:2023-11-28 05:12:59 26 4
gpt4 key购买 nike

不确定问题的表述是否正确,但这就是问题所在。

我有一个静态库,其中 a.h 中有以下类:

#pragma once
#include <vector>
class A{
public:
void Run() {
data_.push_back(10);
std::cout << "size: " << data_.size() << std::endl;
}
private:
static std::vector<int> data_;
};

a.cpp如下:

#include "a.h"
std::vector<int> A::data_;

我在 b.h 中还有另一个类:

#pragma once
#include <string>
class B
{
public:
static std::string Get();
};

和b.cpp:

#include "b.h"
#include "a.h"
std::string B::Get()
{
static A a;
a.Run();
return "foo";
}

现在我使用上述静态库的主要应用程序如下:

#include <iostream>
#include "a.h"
#include "b.h"

static std::string var1= B::Get();

int main(int argc, char** argv)
{
A a;
a.Run();
}

试图理解为什么输出是:

尺寸:1

尺寸:1

整个类的每个静态数据成员应该有一个实例,所以应该有一个对 A::data_ 构造函数的调用。我在打"static initialization order fiasco"吗? IE。 data_ 在我使用它之前没有初始化,但我应该会崩溃?

现在让我们想象一下我的 data_ 包含动态初始化的项目(不是 POD 的东西)。如果最后 data_ 包含一项,尽管我插入了 2 项,它将如何被破坏?

这就是我现实生活中代码中实际发生的事情(它有时会在数据销毁期间崩溃_)。

摆脱全局静态(static std::string var1= B::Get();)解决了问题,但我仍然想了解底层问题。

描述的案例可以在 VS2015 中重现(真实案例可以在 gcc 6.2 中重现)

最佳答案

Am I hitting "static initialization order fiasco"?

很有可能。

您可以通过函数调用使类的 static 数据可用,从而解决此问题。例如

class A{
public:
void Run() {
getData().push_back(10);
std::cout << "size: " << getData().size() << std::endl;
}
private:
static std::vector<int>& getData();
};

std::vector<int>& A::getData()
{
static std::vector<int> data;
return data;
}

当您这样做时,data 将在第一次调用 A::getData() 时被初始化。它完全消除了静态初始化顺序问题。

关于c++ - 通过调用 C++ 中的静态类函数初始化的全局静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43170866/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com