想象一下,我有这样的图书馆:
Library.h
class DLLEXPORT LibraryClass
{
private:
int _id;
static int _last_id;
public:
LibraryClass();
bool operator == (const LibraryClass t)
{return _id == t._id;}
};
Library.cpp
#include "Library.h"
int LibraryClass::_last_id = 0;
LibraryClass::LibraryClass()
_id(_last_id)
{
++_last_id;
}
它能正常工作吗?我在Visual Studio中收到C4835警告,但似乎有效。有谁知道它将如何在其他编译器上工作(我对linux gcc和mac gcc感兴趣)?这种模式还有另一个“有效”的实现吗?
答案 0 :(得分:1)
您的语法很好,这不会导致您的代码出现任何问题;在编译时,我认为你不会在UNIX / MAC系统上看到任何警告(除了你正在进行面向Windows的DLL导出这一事实)。我相信你只是看到托管C ++的后果。
来自MSDN:
'variable':导出数据的初始值设定项将不会运行直到 托管代码首先在主机程序集中执行
在托管组件之间访问数据时,建议使用 您不使用本机C ++导入和导出机制。相反,宣布 您的数据成员在托管类型中并引用元数据 在客户端使用#using。有关更多信息,请参阅#using Directive (C / C ++)。
在unix上编译时,您的静态数据成员将位于程序的初始化测试段中。它保证初始化为您在执行之前提供的值,因此它将从0开始,并且在调用它时它将在构造函数中完全可用。
答案 1 :(得分:1)
从documentation看来,只有在初始化阶段(main
之前)尝试使用该值时才会出现问题。显然是与托管模式相关的问题。
C ++标准非常明确:_last_id
它将在任何动态初始化之前首先静态初始化为0
,这意味着任何符合条件的编译器都将生成可以按预期工作的代码。
因此,它适用于gcc和clang(无论操作系统如何)。
对于Visual Studio,我不确定(不够精明)是否系统地出现问题,或者仅当您需要带有一些标志的托管模式时。