简体   繁体   English

C ++中的静态初始化

[英]Static initialization in C++

Hi, all! 大家好!

I'm developing winForm app on visual C++ (managed code). 我正在开发visual C ++(托管代码)上的winForm应用程序。 This app link native static library which contain block of code with static variable initialization: 此应用程序链接本机静态库,其中包含带有静态变量初始化的代码块:

Cls.h Cls.h

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

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

Cls.cpp Cls.cpp

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

Cls::Cls(void)
{
}

Cls Cls::_instance;

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

I can link those library successfully, but when I try to use getInstance() method I get a run-time error before invoke main function of my app. 我可以成功链接这些库,但是当我尝试使用getInstance()方法时,我在调用我的应用程序的main函数之前会遇到运行时错误。

It's a third party library, so I cannot rebuild it or redefine Cls class on any other way. 它是第三方库,所以我无法重建它或以任何其他方式重新定义Cls类。

App project uses /clr , entry point defined as main . App项目使用/ clr ,入口点定义为main

I tired to search a solution. 我厌倦了搜索解决方案。 I found that I must change entry point, but I don't know what value would be correct. 我发现我必须改变切入点,但我不知道什么值是正确的。

Please, help! 请帮忙!

You're encountering the notorious "static initialisation order fiasco". 你遇到了臭名昭着的“静态初始化命令惨败”。 When static objects are defined in two translation units, it's unspecified which is initialised first; 当静态对象在两个翻译单元中定义时,它是未指定的,首先被初始化; so, if the constructor of one refers to the other, you could end up accessing it before it is initialised. 所以,如果一个的构造函数引用另一个,那么在初始化之前你最终可能会访问它。 The only guarantee is that they will all be initialised before main begins. 唯一的保证是它们都将在main开始之前进行初始化。

The best solution is to avoid static objects. 最好的解决方案是避免静态对象。 In particular, the Singleton anti-pattern that you are using is rather tricky to get right in C++, and is generally more trouble than it's worth. 特别是,你使用的Singleton反模式在C ++中使用起来相当棘手,而且通常比它的价值更麻烦。

If you really want to do this, then you can work around the fiasco by defining the static object inside a function: 如果你真的想这样做,那么你可以通过在函数内定义静态对象来解决这个问题:

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

This has the disadvantage that it introduces a "destruction order fiasco" (where it might not be safe to access from the destructor of another static object), and that it might not be thread-safe in some compilers (although it should be in any that claims C++11 compliance). 这样做的缺点是它引入了“破坏命令惨败”(从另一个静态对象的析构函数访问它可能不安全),并且在某些编译器中它可能不是线程安全的(尽管它应该在任何编译器中)声称符合C ++ 11标准)。 If construction is thread-safe, then there will be a (small) runtime cost for each access, which might be a problem if you have extreme performance issues. 如果构造是线程安全的,那么每次访问都会有(小)运行时成本,如果您遇到极端性能问题,这可能会成为一个问题。

UPDATE: I've just noticed that you say that this evil class is outside your control and can't be changed. 更新:我刚刚注意到你说这个邪恶的阶级不在你的控制范围之内,无法改变。 In that case, your options are: 在这种情况下,您的选择是:

  • Get rid of this library and use something less insane, or 摆脱这个库,并使用一些不那么疯狂的东西,或
  • Be careful not to access any of its static data until main has begun; main开始之前,小心不要访问任何静态数据; in particular, follow my advice above and avoid any static objects of your own. 特别是,请遵循我的建议,避免使用自己的静态物体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM