gpt4 book ai didi

c++ - C++ 中的静态初始化

转载 作者:行者123 更新时间:2023-11-30 02:03:49 25 4
gpt4 key购买 nike

大家好!

我正在 Visual C++(托管代码)上开发 winForm 应用程序。此应用程序链接 native 静态库,其中包含带有静态变量初始化的代码块:

Cls.h

class Cls
{
public:
static Cls* getInstance();

private:
static Cls _instance;
protected:
Cls(void);
};

Cls.cpp

#include "StdAfx.h"
#include "Cls.h"

Cls::Cls(void)
{
}

Cls Cls::_instance;

Cls* Cls::getInstance()
{
return &_instance;
}

我可以成功链接这些库,但是当我尝试使用 getInstance() 方法时,我在调用我的应用程序的主要功能之前遇到了运行时错误。

这是一个第三方库,所以我无法重建它或以任何其他方式重新定义 Cls 类。

应用程序项目使用/clr,入口点定义为main

我厌倦了寻找解决方案。我发现我必须更改入口点,但我不知道什么值才是正确的。

请帮忙!

最佳答案

您遇到了臭名昭著的“静态初始化顺序失败”。当在两个翻译单元中定义静态对象时,未指定哪个先初始化;因此,如果一个的构造函数引用另一个,您可能会在初始化之前访问它。唯一的保证是它们都将在 main 开始之前被初始化。

最好的解决办法是避免使用静态对象。特别是,您正在使用的 Singleton 反模式在 C++ 中是相当棘手的,而且通常比它的值(value)更麻烦。

如果你真的想这样做,那么你可以通过在函数中定义静态对象来解决这个问题:

Cls* Cls::getInstance()
{
static Cls _instance;
return &_instance;
}

它的缺点是引入了“析构顺序失败”(从另一个静态对象的析构函数访问可能不安全),并且在某些编译器中它可能不是线程安全的(尽管它应该在任何声称符合 C++11 的情况下)。如果构造是线程安全的,那么每次访问都会有一个(小的)运行时成本,如果您有极端的性能问题,这可能会成为一个问题。

更新:我刚刚注意到您说这个邪恶的类不在您的控制范围内并且无法更改。在这种情况下,您的选择是:

  • 摆脱这个库并使用一些不那么疯狂的东西,或者
  • 注意在 main 开始之前不要访问它的任何静态数据;特别是,请遵循我上面的建议,避免使用任何属于您自己的静态对象。

关于c++ - C++ 中的静态初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11415383/

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