gpt4 book ai didi

c++ - 局部静态变量被多次实例化,为什么?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:56:40 25 4
gpt4 key购买 nike

我对从这段代码中得到的结果感到困惑。在一个 dll 中,计数器在初始化静态变量时递增。然后,当执行 main 时,我读取了这个计数器,但我得到的是 0 而不是 1。有人可以向我解释一下吗?

在我的动态库项目中:

// Header file
class Foo {
int i_ = 0;

Foo(const Foo&) = delete;
Foo& operator= (Foo) = delete;

Foo()
{
}

public:
void inc()
{
++i_;
}

int geti()
{
return i_;
}

static Foo& get()
{
static Foo instance_;
return instance_;
}

Foo( Foo&&) = default;
Foo& operator= (Foo&&) = default;
};

int initialize()
{
Foo::get().inc();
return 10;
}

class Bar
{
static int b_;

};

// cpp file
#include "ClassLocalStatic.h"


int Bar::b_ = initialize();

在我的应用项目中

// main.cpp
#include <iostream>

#include "ClassLocalstatic.h"

int main(int argc, const char * argv[])
{
std::cout << Foo::get().geti();
return 0;
}

最佳答案

可执行文件和 DLL 都将获得它们自己的 Foo::get() 拷贝,每个拷贝都有自己的静态变量拷贝。因为它们位于单独的链接器输出中,所以链接器无法像往常一样合并它们。

进一步扩展:

C++ 规范允许在多个翻译单元中定义一个内联函数,只要它们都具有相同的主体;将函数放在头文件中是完全可以的,因为它确保每个拷贝都是相同的。参见 https://stackoverflow.com/a/4193698/5987 .如果内联函数中有静态变量,编译器和链接器需要协同工作以确保它们之间只使用一个拷贝。我不确定确切的机制,但没关系,标准需要它。不幸的是,链接器在生成输出可执行文件或 DLL 后停止访问,并且无法判断该函数在两个地方都存在。

解决方法是将 Foo::get() 的主体从 header 中移出,并将其放入仅在 DLL 中的源文件中。

关于c++ - 局部静态变量被多次实例化,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11962918/

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