-4

In C++ language is there any disadvantage to declare a variable global?

void foo()
{
  int a;
  a=10;
}

int a;
void foo()
{
  a=10;
}

Any differences between them?

4

5 回答 5

19

为什么在不必要时应避免使用全局变量

  • 非局部性——当单个元素的范围有限时,源代码最容易理解。全局变量可以被程序的任何部分读取或修改,因此很难记住或推理每种可能的用途。
  • 没有访问控制或约束检查——程序的任何部分都可以获取或设置全局变量,并且任何关于其使用的规则都可以很容易地被破坏或遗忘。(换句话说,get/set 访问器通常比直接数据访问更可取,对于全局数据更是如此。)通过扩展,在您可能希望运行不受信任的代码的情况下,缺乏访问控制极大地阻碍了实现安全性(例如使用 3rd 方插件)。
  • 隐式耦合——具有许多全局变量的程序通常在其中一些变量之间存在紧密耦合,以及变量和函数之间的耦合。将耦合的项目分组为有凝聚力的单元通常会导致更好的程序。
  • 并发问题——如果全局变量可以被多个执行线程访问,同步是必要的(而且经常被忽略)。当动态链接模块与全局变量时,即使在几十个不同上下文中测试的两个独立模块是安全的,组合系统也可能不是线程安全的。
  • 命名空间污染——全局名称随处可见。当您认为您正在使用本地(通过拼写错误或忘记声明本地)时,您可能会在不知不觉中最终使用全局,反之亦然。此外,如果您必须将具有相同全局变量名称的模块链接在一起,如果幸运的话,您会遇到链接错误。如果你不走运,链接器将简单地将所有使用相同名称的对象视为同一个对象。
  • 内存分配问题——某些环境的内存分配方案使得全局变量的分配变得棘手。在“构造函数”具有分配以外的副作用的语言中尤其如此(因为在这种情况下,您可以表达两个全局变量相互依赖的不安全情况)。此外,当动态链接模块时,可能不清楚不同的库是否有自己的全局实例或全局是否共享。
  • 测试和限制- 使用全局变量的源代码更难测试,因为无法在运行之间轻松设置“干净”环境。更一般地,利用未明确提供给该源的任何类型的全局服务(例如读取和写入文件或数据库)的源由于相同的原因而难以测试。对于通信系统,测试系统不变量的能力可能需要同时运行一个系统的多个“副本”,这会受到任何共享服务(包括全局内存)的使用的极大阻碍,这些共享服务并未作为测试的一部分提供共享.
于 2013-07-26T07:06:49.667 回答
1

全局变量的内存不会自动释放。而作用域变量的内存在块完成后立即被释放。

void foo()
{
  int a;
  a=10;
}

int a将在完成后释放foo

int a;
void foo()
{
  a=10;
}

int a将根据其外部范围被释放foo()

于 2013-07-26T07:07:12.137 回答
0

首先,变量存在于堆栈中,并且仅在函数退出之前有效,并且仅在函数内部可见。其次,它既有效又可以从外部访问。

作为一般规则,您应始终将变量声明为尽可能局部的,因此仅在真正需要时才使用全局变量。

还有第三种变体。如果你这样做:

void foo()
{
static int a;
a=10;
}

然后你的变量在函数退出后仍然有效,但它只能从内部可见(尽管你可以根据需要给出指针或引用)。如果您需要一个需要在函数调用之间保留其值但仅在函数内部使用的变量,这是推荐的用法。

于 2013-07-26T07:10:23.373 回答
0

这已经在 StackOverflow 上讨论过。例如看这个:

https://stackoverflow.com/a/485020/980195

将变量放在全局范围内的主要缺点正是它们变得全局可访问。任何其他代码都可以决定读取或写入它们。而对于局部变量,您只需要查看局部范围即可了解能够更改甚至访问该值的所有内容。

除此之外,将它放在全局命名空间中意味着它可能会导致名称冲突、歧义,甚至用户通过简单的错字意外引用了错误的变量。如果您将变量称为像您的情况一样简单的东西,这尤其糟糕。

还有更多原因,例如查看@naren 提供的答案。

于 2013-07-26T07:11:24.623 回答
0

内存使用情况。在第一种情况下,内存将被释放,在第二种情况下不会。而且,将名称为“A”的变量声明为全局变量是非常糟糕的。这将是大量错误的来源。

于 2013-07-26T07:04:46.443 回答