外部变量 vs 单例模式类

4

假设我们有一些使用extern关键字的外部链接。

我在class1.cpp中有以下代码:

MyClass* myClassVar = NULL;

构造函数初始化上述内容,析构函数删除。
然后在class2.cpp和class3.cpp中有:
extern MyClass* myClassVar;

这些类使用myClassVar(通常进行null检查等)。

是否更喜欢使用Singleton?(我知道全局变量很糟糕等等,而Singleton只是语法糖)。将上述代码更改为下面的代码是否有优势?

static Singleton& getInstance()
{
   static Singleton instance;

   return instance;
}

然后所有的类都会执行:

Singleton::getInstance()
2个回答

7
全局变量遭受了“初始化顺序惨案”的困扰。在不同翻译单元中的全局变量按照未指定的顺序进行初始化,因此如果在构造函数中引用另一个全局变量,则会出现未定义的行为。
函数范围内的静态变量在第一次调用函数时被初始化,这(或多或少地)解决了初始化顺序问题。
然而,更微妙的问题仍然存在;特别是,在对象被销毁后仍然可能访问该对象,并且有一些开销来确保线程安全的初始化(在旧版本编译器中,初始化可能根本不是线程安全的)。没有完全安全的方法来管理非平凡类型的全局可访问对象,我的建议是尽可能避免使用它们。

2
那是一个有趣的困境。作为图形程序员,我不时挖掘各种游戏引擎的源代码。我发现虚幻引擎4(这是C ++)广泛使用单例的extern关键字。现在我不确定这个软件背后的工程师是否是业余爱好者,所以我很疑惑为什么他们更喜欢使用extern而不是static实例单例。 - Michael IV

5

既然您说您已经知道任何类型的全局变量的缺点,那么唯一的优点在于将类的实例限制为1个,而不是使用 extern,在这种情况下,您可以同样定义多个该类型的变量。


你不能真正定义具有相同名称的多个变量,因此差异不存在。 - Alok Save
@Als 我从未说过它们有相同的名称。单例模式完全禁止这种情况(即使使用不同的名称)。 - Luchian Grigore
@LuchianGrigore 并不完全正确。至少在实际情况下不是这样的。没有任何阻止您将单例制成一个对象数组而不是单个对象 :) 尽管这有点违背了单例的初衷。 - s3rius
来吧,你可以定义一个单例,最多只有 num 个副本。这是你可以控制的实现。 - Unicorn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接