声明全局变量的最佳方法是什么?

5 c++ design-patterns

在C++中,假设您要声明一个全局变量供许多人使用.你怎么做呢?

我通常在cpp文件中使用declare和define,然后在其他cpp文件中使用extern(而不是头文件).

我不喜欢这种方法,我正在考虑以下几点:

在头文件中:

some_file.h

Class MYGlobalClass
{

};


MyGlobalClass& MyGlobalClassInstance()
{
   static MYGlobalClass instance; 
   return  instance;

}
Run Code Online (Sandbox Code Playgroud)

编辑

请考虑以下情况:

  • 可用于多线程应用程序
  • 名称空间污染
  • 可能不会成为单身人士,因为可能会创建许多此类实例

你有什么想法,建议,新想法?

jal*_*alf 10

最好的建议可能是"尽量避免全局".人们不像他们想象的那样经常需要全局变量.通常情况下,"将所有内容作为参数传递给构造函数"并不像人们在听到建议时所想的那么多.它还倾向于使用更少,更明确的依赖性来实现更清晰的代码.

我不知道在C++中声明全局变量的任何"正确"方法.你现在的方式工作正常,但初始化的顺序是未指定的,所以如果你的全局变量之间存在任何依赖关系,那你就麻烦了.

返回静态实例的函数或多或少地解决了这个问题,但不是线程安全的.

单身只是一个可怕的想法.它不能解决您的问题,但会为您的代码添加额外的约束,而这些约束实际上并不是必需的,并且很可能会在以后再次出现.


Joh*_*itb 2

在一个头文件中声明它(使用extern),并在一个 .cpp(或任何其他扩展名)文件中定义它。您可以使用函数并返回对静态变量的引用,就像您所展示的那样,以避免相对于其他.cpp文件中的其他此类命名空间范围变量的构造顺序问题。但请记住,这不会保护您免受破坏顺序问题 - 这与构造顺序完全相反(这些东西称为“静态初始化顺序惨败”。如果您使用像您这样的函数并将其放入标头中,请将其内联使函数的重新定义在包含到多个.cpp文件中时有效(从逻辑上讲,该函数仍然只出现一次,因为其中的静态只会存在一次,而不是针对每个包含它的文件单独存在)。或者只需声明它在标头中,但在一个 .cpp文件中定义它(但是,然后从中删除内联!)。

inline A& getA() { static A a; return a; }
Run Code Online (Sandbox Code Playgroud)

销毁顺序的潜在问题可以通过使用来规避new

inline A& getA() { static A *a = new A; return *a; }
Run Code Online (Sandbox Code Playgroud)

然而,它的析构函数永远不会被调用。如果需要线程安全,则应该添加一个互斥体来防止多次访问。boost.thread可能有一些东西。