声明变量全局是否有任何不利之处?

时间:2013-07-26 07:03:22

标签: c++ global-variables

在C ++语言中,声明变量全局是否有任何缺点?

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

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

他们之间有什么不同吗?

5 个答案:

答案 0 :(得分:17)

Why Global Variables Should Be Avoided When Unnecessary

  
      
  • 非本地化 - 当各个元素的范围有限时,源代码最容易理解。可以读取全局变量   或由程序的任何部分修改,使其变得困难   记住或推理每一种可能的用途。
  •   
  • 无访问控制或约束检查 - 程序的任何部分都可以获取或设置全局变量,以及有关其使用的任何规则   很容易被打破或遗忘。 (换句话说,获取/设置访问者   通常比直接数据访问更受欢迎,这是偶数   对于全球数据更是如此。)通过扩展,缺乏访问控制   在您可能希望的情况下,极大地阻碍了安全性   运行不受信任的代码(例如使用第三方插件)。
  •   
  • 隐式耦合 - 具有许多全局变量的程序通常在这些变量之间存在紧密耦合,并且之间存在耦合   变量和函数。将耦合项目分组为有凝聚力的单元   通常会带来更好的计划。
  •   
  • 并发问题 - 如果多个执行线程可以访问全局变量,则需要进行同步(并且经常被忽略)。   当动态链接模块与全局变量,组合系统   即使测试了两个独立模块,也可能不是线程安全的   数十种不同的背景是安全的。
  •   
  • 命名空间污染 - 全球各地都有名称。当你认为你正在使用时,你可能会在不知不觉中最终使用全局   本地(通过拼写错误或忘记宣布当地)或恶习   反之亦然。此外,如果您必须将具有该模块的模块链接在一起   相同的全局变量名称,如果幸运的话,您将获得链接   错误。如果你运气不好,链接器将简单地处理所有用途   与同一对象同名。
  •   
  • 内存分配问题 - 某些环境具有内存分配方案,使得全局分配变得棘手。这是特别的   在“构造函数”除了具有副作用的语言中为true   分配(因为,在这种情况下,你可以表达不安全的情况   两个全局相互依赖的地方)。还有,何时   动态链接模块,可能不清楚是否不同   库有自己的全局变量实例或全局变量   是共享的。
  •   
  • 测试和限制 - 使用全局变量的来源有点难以测试,因为人们无法轻易设置“干净”   运行之间的环境。更一般地说,利用全球的来源   任何形式的服务(例如读写文件或数据库)   未明确提供给该来源的内容很难测试   出于同样的原因。对于通信系统,测试能力   系统不变量可能需要运行系统的多个“副本”   同时,任何使用共享都会受到很大阻碍   服务 - 包括全局内存 - 不提供共享   作为测试的一部分。
  •   

答案 1 :(得分:1)

全局变量的内存不会自动释放。虽然范围变量的内存在块完成后立即释放。

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

int a

完成后,foo将被释放
int a;
void foo()
{
  a=10;
}

int a将根据foo()

之外的范围被释放

答案 2 :(得分:0)

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

答案 3 :(得分:0)

在第一个变量中,变量存在于堆栈中,并且仅在函数退出之前有效,并且仅在函数内部可见。在第二种情况下,它既有效又可从外部访问。

作为一般规则,您应该始终将变量声明为本地变量,因此仅在必要时才使用全局变量。

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

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

然后你的变量在函数退出后仍然有效,但它只能从内部看到(尽管你可以根据需要给出指针或引用)。如果您需要一个需要在函数调用之间保留其值但仅在函数内使用的变量,则建议使用此选项。

答案 4 :(得分:0)

之前已经在StackOverflow上讨论过这个问题。例如,见:

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

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

除此之外,将它放在全局命名空间中意味着它可能引起名称冲突,模糊甚至用户通过简单的拼写错误地引用错误的变量。如果你将变量称为像你的情况一样简单,那就特别糟糕了。

还有更多的理由,例如,请查看@naren提供的答案。