正确的全局变量定义/声明
Posted
技术标签:
【中文标题】正确的全局变量定义/声明【英文标题】:Proper Global Variable definition/declaration 【发布时间】:2021-05-29 18:01:12 【问题描述】:这可能是一个非常直截了当的问题,但由于某种原因,到目前为止我还没有在伟大的互联网上找到答案。
当使用全局变量时,我知道全局变量是不好的,在大多数情况下应该避免使用,但是在极少数情况下全局变量可以最好地完成工作,是否应该同时声明和初始化全局变量?我最近一直在尝试深入研究“尽可能在声明时始终初始化变量”的口头禅,因为这通常会在以后省去很多麻烦,并且在 C++ 中受到鼓励。这条规则是否也适用于全局变量?
如果在声明变量时在其全局范围内初始化变量,这对程序有何影响?这是最佳做法吗?
非常感谢您的建议!
【问题讨论】:
始终初始化全局变量!(或者编译器会使用标准值为您执行此操作) 【参考方案1】:是的,您确实想初始化全局变量。正如@paladin 评论的那样,如果您不初始化它们,编译器将尝试使用默认值初始化它们。 考虑这个简单的例子:
struct Foo
Foo(int x, char *y, double z)
;
Foo f;
编译器会尝试初始化f
,但没有默认构造函数。这会配置一个错误:
<source>:5:5: error: no matching constructor for initialization of 'Foo'
Foo f;
^
<source>:1:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
所以是的,您需要初始化全局变量,如果您不这样做,编译器会尝试为您完成。
【讨论】:
【参考方案2】:您希望尽可能在声明变量时对其进行初始化,而不管其范围如何。
对于全局变量,如果在声明它们时不对其进行初始化,则需要在程序开始运行后对其进行初始化,这样就可能在此之前使用全局变量。具有构造函数的类将是默认构造的,这可能会导致在为变量分配适当的值时完成工作并丢弃。
全局变量还有另一个问题:它们的构造/初始化顺序仅由语言部分定义。如果你有两个在不同源模块中声明的全局变量,你不知道会先构造哪个。这可能会导致静态初始化顺序惨败。
因此,如果您初始化它们,您可能会遇到问题,或者如果您不初始化它们,则会遇到不同的问题。这是应该避免使用全局变量的原因之一。
解决办法是什么?您可以将全局变量包装到访问器函数中。这将确保变量已正确初始化。因此,而不是简单的声明:
SomeType big = ReadBig();
你可以把它放到一个函数中:
const SomeType &GetBig()
static SomeType big = ReadBig();
return big;
这还有一个好处是你的全局变量const
,所以如果有必要,它不能被改变。
【讨论】:
"静态初始化顺序惨败" 不是只有在这些全局变量不相互独立时才会发生吗? (如果这些全局变量不是相互独立的,那么您至少有 1 个全局变量太多了。)我也很确定全局变量也可能是全局常量。我发现您在函数的帮助下重新发明全局变量的方法很好奇。我认为那里没有优势,但有劣势。 @paladin 如果全局变量是独立的,那么它们的构造顺序无关紧要。当顺序很重要时就会出现问题。让函数返回指向局部静态变量的引用或指针的方法很常见。工厂模式的一种实现将做到这一点(类的静态成员函数返回对函数内声明的局部静态变量的引用)。以上是关于正确的全局变量定义/声明的主要内容,如果未能解决你的问题,请参考以下文章