在C++中,如何最好地使用全局变量?

3

对我而言,通常会创建一个全局类,其中所有成员都是静态的。其他所有类都将从此全局类继承。

我想知道这是否是一种好的实践方式?

有人有什么建议吗?


5
为什么要使用全局变量? - Chris Dodd
如果所有成员都是静态的,并且类可以全局访问,为什么还需要继承它?如果字段是公共的,你可以使用命名空间::类名::成员名来访问。 - Steve Guidi
3
这个问题可怕的地方在于,我本来可以把它写成愚人节玩笑,虽然我会尝试加入至少一个附加的坏主意。 - David Thornley
5
哈哈!终于有个好问题了!等等,这是一个认真的问题吗? - John Dibling
7个回答

6
通常情况下,应尽量避免使用全局变量,因为它们引入了全局状态。而全局状态会导致无法实现引用透明性,而引用透明性是一件好事,而全局状态则是一件坏事。例如,全局状态使得单元测试几乎没有意义。
但如果必须使用全局变量,我同意你提到的方法在大多数情况下都是可行的。你也可以在任何 .cpp 文件中声明全局变量,然后在你的 .h 文件中使用 extern 来引用该全局变量。

你是否想要一个全局状态,在调试类或一组调试函数中,以允许随着时间的推移将输出发送到一个中心窗口或控制台。有些东西很难调试,比如带有临界区的线程... - Eric

1

有两件事让我感到烦恼:使用全局变量是不好的,但有时候难以避免,然而我感到烦恼的是:

  • 滥用继承
  • 依赖问题

这两者的结合效果惊人。

假设我创建一个将访问全局变量的类,从你的反模式中得出:

#include "globals.h"

class MyClass: Globals // for my own sake I assume it's not public inheritance
{
};

当然,#include在头文件中是必须的,因为我从中继承。因此,每次我添加/更改全局变量之一,即使只有一个类使用它...我都需要重新编译整个应用程序。

如果我们曾经在同一个团队工作过,那么这将会引起你非常严厉、非常严肃的评论...至少可以这么说。


1
嗨!你好!有什么我可以帮助你的吗?

1

你提出的做法并没有解决与全局变量相关的问题。

  • 使用私有成员数据和访问函数可以实现单一控制读/写和验证,提高了程序的稳定性、可维护性和调试的便捷性。
  • 将数据成员定义为静态的只会降低代码的灵活性;你可能希望包含相同数据结构的多个独立的全局对象。如果确保只存在一个对象,可以使用单例模式。
  • 将无关的全局数据集中到一个类中打破了最佳耦合和内聚度的实践原则,而且也不太符合面向对象的编程思想。

本文是与C语言和嵌入式系统相关的,但同样适用于你的问题。


1

首先,全局状态很糟糕。它会严重复杂化程序的理解,因为任何部分的行为都可能依赖于全局变量。它使测试变得更加困难。它提供了一种方式,使得两个遥远的函数可以创建一个不一致的状态,可能会破坏另一个函数,并且这将非常难以进行调试。

全局状态的性质并不重要。这通常是Singleton模式所诟病的地方。

然而,让每个类继承自一个全局变量类是一个不好的想法。在C++中,应该谨慎使用继承,因为它会将两个类在实现上联结在一起。通常,在任何形式下都不应该让所有的类都从一个基类继承,而且C++并不处理多重继承非常好。由于如果A继承自B并且它们都从Global继承,那么Global将出现两次在A的继承层次结构中,因此很容易出现“致命菱形”效应。


0

糟糕!

全局变量就是全局变量。即使用一个看起来像成员变量的名称对其重新命名,也不会改变这一点。你在普通全局变量上遇到的每个问题,在将其作为公共静态成员的全局变量方案中仍然存在(可能还有一些新问题)。


-1
你很可能正在寻找单例模式。这并不意味着所有的全局变量都需要使用该模式。但是,当我有一个全局变量时,通常是因为我希望整个程序只有一个实例化对象。在这种情况下,单例模式可以非常有效地工作。

http://en.wikipedia.org/wiki/Singleton_pattern


1
如果你只想要一个实例化对象,那就只实例化一个。没必要把事情搞得过于复杂。http://jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-know-you-never-had-since-1995/ - GManNickG

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