库和导出C++中的静态变量

Libraries and exporting static variables in C++

本文关键字:静态 变量 C++      更新时间:2023-10-16

想象一下我有这样的库:

图书馆.h

   class DLLEXPORT LibraryClass
    {
    private:
      int _id;
      static int _last_id;
    public:
      LibraryClass();
      bool operator == (const LibraryClass t)
      {return _id == t._id;}
    };

图书馆.cpp

#include "Library.h"
int LibraryClass::_last_id = 0;
LibraryClass::LibraryClass()
_id(_last_id)
{
++_last_id;
}

它会正确工作吗?我在Visual Studio中收到C4835警告,但似乎它可以工作。有谁知道它将如何在其他编译器上工作(我对Linux gcc和mac gcc感兴趣)?这种模式是否有另一个"有效"实现?

你的语法很好,这应该不会在你的代码中引起任何问题;我认为在编译时,您不会在 UNIX/MAC 系统上看到任何警告(除了您正在执行面向窗口的 DLL 导出这一事实)。 我相信你只是看到了管理C++的后果。

从 MSDN:

'variable' :导出数据的初始值设定项将运行,直到 托管代码首先在宿主程序集中执行

在托管组件之间访问数据时,建议 不使用本机C++导入和导出机制。相反,声明 托管类型中的数据成员并引用元数据 客户端中 #using。有关详细信息,请参阅 #using 指令 (C/C++)。

在 unix 上编译时,您的静态数据成员将位于程序的初始化测试段中。 它保证在执行之前初始化为您提供的值,因此它将从 0 开始,并且在调用它时它将在您的构造函数中完全可用。

从文档中看,似乎只有在您尝试在初始化阶段(在 main 之前)使用该值时才会出现问题。显然是与托管模式有关的问题。

C++标准对此非常明确:_last_id它将首先静态初始化为0,然后再进行任何动态初始化,这意味着任何符合标准的编译器都将生成按预期工作的代码。

因此,它将与 gcc 和 clang (无论操作系统如何)一起使用。

对于 Visual Studio,我不确定(不够精明)问题是否会系统地出现,或者仅当您需要带有某些标志的托管模式时才出现。