适当的全局变量 definition/declaration
Proper Global Variable definition/declaration
这可能是一个非常直截了当的问题,但出于某种原因,到目前为止我还没有能够在伟大的互联网上找到答案。
当使用全局变量时,我知道全局变量不好,在大多数情况下应该避免,但在极少数情况下,全局变量最能发挥作用,全局变量是否应该同时声明和初始化一次?我最近一直试图在我的脑海中钻研“总是尽可能在声明时初始化变量”的口头禅,因为这通常会在以后避免很多麻烦,并且鼓励使用 C++。这条规则也适用于全局变量吗?
如果在声明变量时在其全局范围内初始化变量,这对程序有何影响?这是最佳做法吗?
非常感谢您的建议!
是的,您确实想要初始化全局变量。正如@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
所以是的,您需要初始化全局变量,如果您不这样做,编译器会尝试为您完成。
您希望尽可能在声明变量时初始化变量,而不考虑它们的作用域。
对于全局变量,如果声明时不初始化,则需要在程序启动后初始化运行ning,这就留下了在此之前使用全局变量的可能性发生。 类,使用构造函数,将被默认构造,这可能会导致工作完成并在变量被分配适当的值时被抛出。
全局变量还有另一个问题:它们的顺序 constructed/initialized 仅部分由语言定义。如果在不同的源模块中声明了两个全局变量,您将不知道先构造哪个。这会导致静态初始化顺序惨败。
因此,如果您初始化它们,您可以 运行 遇到问题,如果不初始化,则可能会遇到不同的问题。这是应该避免使用全局变量的原因之一。
解决方法是什么?您可以将全局变量包装到访问函数中。这将确保变量已正确初始化。所以而不是简单的声明:
SomeType big = ReadBig();
你可以把它放到一个函数中:
const SomeType &GetBig() {
static SomeType big = ReadBig();
return big;
}
这也有一个优点,即拥有全局变量 const
,因此如果有必要则无法更改。
这可能是一个非常直截了当的问题,但出于某种原因,到目前为止我还没有能够在伟大的互联网上找到答案。
当使用全局变量时,我知道全局变量不好,在大多数情况下应该避免,但在极少数情况下,全局变量最能发挥作用,全局变量是否应该同时声明和初始化一次?我最近一直试图在我的脑海中钻研“总是尽可能在声明时初始化变量”的口头禅,因为这通常会在以后避免很多麻烦,并且鼓励使用 C++。这条规则也适用于全局变量吗?
如果在声明变量时在其全局范围内初始化变量,这对程序有何影响?这是最佳做法吗?
非常感谢您的建议!
是的,您确实想要初始化全局变量。正如@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
所以是的,您需要初始化全局变量,如果您不这样做,编译器会尝试为您完成。
您希望尽可能在声明变量时初始化变量,而不考虑它们的作用域。
对于全局变量,如果声明时不初始化,则需要在程序启动后初始化运行ning,这就留下了在此之前使用全局变量的可能性发生。 类,使用构造函数,将被默认构造,这可能会导致工作完成并在变量被分配适当的值时被抛出。
全局变量还有另一个问题:它们的顺序 constructed/initialized 仅部分由语言定义。如果在不同的源模块中声明了两个全局变量,您将不知道先构造哪个。这会导致静态初始化顺序惨败。
因此,如果您初始化它们,您可以 运行 遇到问题,如果不初始化,则可能会遇到不同的问题。这是应该避免使用全局变量的原因之一。
解决方法是什么?您可以将全局变量包装到访问函数中。这将确保变量已正确初始化。所以而不是简单的声明:
SomeType big = ReadBig();
你可以把它放到一个函数中:
const SomeType &GetBig() {
static SomeType big = ReadBig();
return big;
}
这也有一个优点,即拥有全局变量 const
,因此如果有必要则无法更改。