在C ++中,假设您要声明一个全局变量供许多人使用。你是怎么做到的?
我通常在cpp文件中使用declare和define,然后在其他cpp文件中使用extern(而不是标题)。
我不喜欢这种做法,我正在考虑这些方面:
在头文件中:
some_file.h
Class MYGlobalClass
{
};
MyGlobalClass& MyGlobalClassInstance()
{
static MYGlobalClass instance;
return instance;
}
修改
请考虑以下情况:
您有什么想法,建议,新想法?
答案 0 :(得分:10)
最好的建议可能是“尽量避免全局”。人们不像他们想象的那样经常需要全局变量。通常情况下,“将所有内容作为参数传递给构造函数”并不像人们在听到建议时所想的那么多。它还倾向于使代码更清晰,具有更少,更明确的依赖性。
我不知道在C ++中声明全局变量的任何“正确”方法。你现在的方式工作正常,但初始化的顺序是未指定的,所以如果你的全局变量之间存在任何依赖关系,那你就麻烦了。
返回静态实例的函数或多或少地解决了这个问题,但不是线程安全的。
单身只是一个可怕的想法。它不能解决您的问题,但会为您的代码添加额外的限制,这些限制实际上并不是必需的,并且很可能会在以后再次出现并咬你。
答案 1 :(得分:4)
在“many”包含的一个头文件中声明为extern,并在一个* .cpp文件中定义
答案 2 :(得分:2)
您对存取器函数内部静态的想法与全局变量有很大不同。不同之处在于构造时,并且最有可能是多线程的主要问题。如果两个线程同时调用MyGlobalClassInstance
怎么办?根据环境的不同,但我怀疑这是大多数C ++编译器的典型特征,您可能会同时运行MyGlobalClass
的构造函数的两次调用,同时处理相同的内存区域。
如果你是单线程的话,它不太可能成为问题。
如果您将实例声明为普通静态成员或源文件中的普通全局变量,您可能会有更轻松的时间,因为构造函数将在main
执行之前被调用,之后有机会开始其他线程。
答案 3 :(得分:2)
在一个头文件中声明它(使用extern
),并在 one .cpp
(或其他任何扩展名)文件中定义它。您可以使用函数并返回对静态变量的引用,就像您展示的一样,以避免相对于其他.cpp
文件中的其他此类命名空间范围变量的构造顺序问题。但请记住,这不会保护您免受破坏顺序问题的影响 - 这与构造完全相反(这些东西称为“静态初始化顺序惨败”。如果您使用类似于您的函数并将其放入标题中,请将其内联当函数被包含在多个.cpp
文件中时,重新定义函数是有效的(逻辑上,该函数仍然只有一次,因为它中的静态只存在一次,而不是单独存在于每个文件中或者只是在标题中声明它,但在一个 .cpp
文件中定义它(但是,然后从中删除内联!)。
inline A& getA() { static A a; return a; }
使用new
:
inline A& getA() { static A *a = new A; return *a; }
然而,它的析构函数永远不会被调用。如果您需要线程安全,则应添加一个防止多次访问的互斥锁。 boost.thread
可能有一些东西。
答案 4 :(得分:1)
在cpp文件中声明和定义
将extern
- ed声明保留在标题中。在实现文件中仅将定义为。
你很亲密。使用命名空间代替全局变量。
namespace myns {
int foo = 0;
}
现在,如果它是一个类对象,那么您正在查看Singletion模式。实际上,您的示例代码反映了Singleton设计。但是,如果要在标头中定义函数,请将其设置为内联 - 否则将导致ODR违规。
答案 5 :(得分:1)
它真的是一个全局变量,理论上可以被任何模块从外部访问,你应该将extern声明放在头文件中:
// MyClass.h
class MyClass { ... };
extern MyClass myGlobalInstance;
// MyClass.cpp
MyClass myGlobalInstance;
如果它只是一个真正只能由单个模块访问的全局对象,则通过将其作为私有(或受保护的)静态类变量,静态函数变量(如果只需要一个函数)来限制其作用域,或在匿名命名空间中:
选项1:
// MyClass.h
class MyClass
{
private: // or protected, if you want it accessible by subclasses
static MyClass myGlobalInstance;
};
选项2:
// MyClass.cpp
void someFunction()
{
// it's global, but only accessible inside this function
static MyClass myGlobalInstance;
...
}
选项3:
// MyClass.cpp
namespace
{
MyClass myGlobalInstance;
}
// it's now only accessible in this file
答案 6 :(得分:0)
extern MyGlobalClass MyGlobalClassInstance;
修改:非静态>。<
答案 7 :(得分:-1)
为什么不使用好的旧单身模式?