在这种情况下我应该使用静态吗?

时间:2011-04-26 07:52:22

标签: c++ windows

我有一个全局唯一值,我希望在exe和不同的DLL中使用它。

对于任何希望使用它的项目,它们可能只包括defs.h

我想知道,我应该将其声明为

// defs.h
const UINT UNIQUE_MESSAGE = 
    RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

OR

// defs.h
const static UINT UNIQUE_MESSAGE = 
    RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

目前,我没有发现任何与代码消费者观点不同的观点。是否有任何陷阱?我应该使用static吗?

3 个答案:

答案 0 :(得分:8)

在C ++中,命名空间级别 const隐式statici.e it has internal linkage),除非您编写extern const。所以你的语法基本相同。

§7.1.1/ 6说,

  

声明为const且未显式声明为extern的对象具有内部链接。

所以我建议这样做:(最少考虑,例如排除static initialization order fiasco以及static和全局变量的许多其他问题)

//in defs.h:
extern const UINT UNIQUE_MESSAGE;

//defs.cpp
const UINT UNIQUE_MESSAGE =  RegisterWindowMessage(_T("whatever"));

答案 1 :(得分:1)

包含defs.h的每个CPP文件都将在内存中拥有自己的const实例。如果你想在内存中只有一个实例,你必须在cpp文件中声明一次,就像你做的那样:

const UINT UNIQUE_MESSAGE = RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

在def.h中,你必须将const引用为外部:

extern const UINT UNIQUE_MESSAGE;

答案 2 :(得分:0)

如果您提供的示例是正确的,那么我将关注您的头文件重新声明并为其包含的每个文件初始化此值的事实。如果在没有名称空间的多个文件中声明,您将最终具有相同符号的多个声明。

此外,即使这只是一个声明,并且实现是在一个单独的源文件中,静态全局变量存在许多值得注意的问题,包括非局部静态全局变量的初始化顺序(一个文件中的一个全局化的初始化程序取决于另一个全局在一个单独的文件中被初始化 - 单独文件中的全局变量的初始化顺序是不确定的。一个更理智的方法(由Scott Meyers在Effective C ++中解释)可能是使用:


defs.h:
const UINT getUniqueMessage();

defs.c:
const UINT getUniqueMessage()
{
static UINT UNIQUE_MESSAGE = RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}")); // initialized once first time called
return UNIQUE_MESSAGE;
}

现在可以在任何地方调用getUniqueMessage(),包括在其他全局变量的初始化期间,而不用担心使用可能尚未初始化的东西。