全局变量不好(在这种情况下)吗?
好吧,我第一百万次坐下来告诉自己“我要使用 SDL 和 C++ 编写一个游戏”,除了这一次我告诉自己我要用 C 编写它。这是因为 SDL 本身是用 C 编写的这对我来说似乎很有意义。我正在编写的游戏将是一个简单的“SHMUP”(射击它们),并且它的代码可能会非常短,所以我想知道几个全局变量是否不好? (比如“struct base basevar;”或“int SCREEN_W”之类的)?
Well here I am sitting down for the millionth time telling myself "I'm going to write a game using SDL and C++" except this time I told myself I was going to write it in C. This is because SDL itself is written in C and it seems to just make sense to me. The game that I'm writing will be a simple "SHMUP" (Shoot 'em up) and it will probably be very short code-wise, so I'm wondering are a couple global variables bad? (like "struct base basevar;" or "int SCREEN_W" or something)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
全局变量本质上并不是“坏”的。然而,如果不小心使用,它们很容易导致非常糟糕的代码(在可读性、可测试性、可维护性方面)。如果使用不慎,它们还可能导致有害的多线程问题(如果您使用线程)。
有些人有一条笼统的规则,那就是你永远不应该使用它们。恕我直言,这太严厉了,如果严格遵循,可能会导致人们将一个指向大
everything_t
的指针传递给所有函数,这并没有好多少(尽管即使这种简单的方法也使您的代码可重入)。但是,请不要将此视为“尽情使用全局变量!”的鼓吹。仅在少数情况下它们才是正确的答案。在你的例子中,听起来你有一堆设置/参数并没有真正改变。至少考虑将它们分组到一个
settings
结构中;这使您以后可以灵活地使用const settings *getSettings()
函数。Global variables aren't inherently "bad". However, they can easily lead to very bad code (in the sense of readability, testability, maintainability) if used carelessly. They can also lead to pernicious multi-threading issues (if you're using threads), again, if used carelessly.
Some people have a blanket rule that you should never use them. IMHO, this is too draconian, and if followed religiously, can lead to people passing around a pointer to a big
everything_t
to all functions, which isn't a great deal better (although even this simple approach makes your code re-entrant). However, please don't read this as advocation for "just go wild with globals!". They are the right answer only in a few situations.In your example, it sounds like you have a bunch of settings/parameters that don't really change. Consider at least grouping them into a
settings
struct; this gives you the flexibility later to have e.g. aconst settings *getSettings()
function.好吧,让我们考虑一下为什么全局变量被认为是不好的。这是他们不受限制的可见性。所有代码都可以访问全局变量,以进行读取和修改。基于全局变量扩散的设计破坏了结构。读取和写入可以来自任何地方。虽然当你第一次实现某些东西时这可能没问题(因为你了解这方面的情况),但由于它鼓励的代码类型,这可能会是灾难性的。很快你就会得到一堆人际关系和互动的意大利面条。
话虽如此,对全局变量的盲目仇恨也是没有道理的。我的意思是,全球化可能是相对的。类名在命名空间内是全局的。类成员在该类建立的命名空间内是全局的。因此,如果一个类的代码库变得足够大,那么针对全局变量的相同论点可能也会针对类成员。事实上,命名空间和类在某种程度上是遏制这种全局性疾病的机制。它们(部分)是划定可见性和访问边界的机制。
因此,在我看来,全球化不是问题。这实际上是关于它如何影响结构。
Well, let's consider why globals are considered bad. It's their unconstrained visibility. Global variables are accessible to all code, for reads and modifications. A design based on proliferation of globals, defeats structure. The reads and writes can come from anywhere. And while this may be OK when you first implement something (because you know the land), it can be catastrophic because of the kind of code it encourages. Soon you end up with a spaghetti of relationships and interactions.
Having said this, a blind hatred of globals is also not warranted. I mean, globalness can be relative. A class name is global within a namespace. A class member is global within the namespace established by the class. So, if the codebase for a class becomes large enough, the same argument made against globals, can likely be made against class members. In fact, namespaces and classes are, in part, mechanisms to contain this disease of globalness. They are (in part) mechanisms to draw boundaries of visibility and access.
So, in my view, globalness is not the issue. It's really about how it affects structure.
虽然在这种情况下可能不是致命的,但您不知道将来要如何处理代码。如果游戏变大,全局变量将使调试变得困难。如果您决定将代码重新用于另一个游戏,甚至用于同时绘制 2 个屏幕的游戏,那么全局变量将会妨碍您。
即使它不重要,你也应该练习良好的编程风格,这样当它重要时你就能做对。
While probably not deadly in this situation, you don't know what you'll want to do with your code in the future. If the game gets bigger, global variable will make debugging hard. If you decide to re-use the code for another game or even for something drawing 2 screens at once, the globals will get in the way.
You should practice good programming style even when it doesn't matter so you'll get it right when it does.
这取决于您是否计划重用该代码。如果您计划将代码更改为其他内容,那么请不要使用全局变量,因为它们非常难以分解。
It depends on whether or not you plan on re-using the code. If you ever plan on changing the code into anything else, ever, then do not use a global, because they're incredibly hard to factor out.
最好知道某些环境,特别是旧版本的 Symbian 不支持全局变量,甚至静态局部变量。
It could also be good to know that some environments, specifically old versions of Symbian doesn't support global variables, or even static locals.