考虑一个具有重载构造函数的类Cow 牛:牛(int i);
现在我静态分配 牛myCow(4);
这个非默认构造函数是否正常运行? 这是一个好习惯还是有任何陷阱?
答案 0 :(得分:3)
这取决于静态的范围。
在文件范围内,静态变量在调用main()
之前的某个时刻初始化。初始化顺序未定义,因此您不能依赖它。请注意,为了初始化计时的目的,类的静态成员处于文件范围。
e.g。
static X global_x; // initialised before main() is called
如果静态变量是在函数范围定义的,则在程序第一次流过它时初始化。是的,这意味着如果从未调用该函数,则永远不会初始化该函数。同样,为了我们的目的,函数,方法和静态方法被等效地处理。
e.g。
X& func()
{
static X my_x; // initialised the first time the program counter gets here
return my_x;
}
附录进一步理解:
同一翻译单元中的文件范围静态以顶级顺序初始化,因此它们的初始化顺序相对于彼此是可预测的。翻译单位之间无法预测订单。
静态物体的破坏严格按照与施工相反的顺序进行,无论可能是什么。这给出了一定程度的可预测性,意味着(例如)函数范围静态可能依赖于另一个函数范围静态或文件范围静态的生命周期...假设函数范围静态未被另一个文件初始化-scope static在不同的翻译单元中: - )
演示:
这是一个用于说明初始化和去初始化顺序的小演示。请注意,函数make_fox()
在main()
之前调用。需要小心。
#include <iostream>
using namespace std;
struct chicken
{
chicken() { std::cout << "chicken" << std::endl; }
~chicken() { std::cout << "~chicken" << std::endl; }
};
chicken licken;
class fox;
fox& make_fox();
struct eagle
{
eagle() { std::cout << "eagle" << std::endl; }
~eagle() { std::cout << "~eagle" << std::endl; }
fox& _fox = make_fox();
};
class fox
{
fox() { std::cout << "fox" << std::endl; }
~fox() { std::cout << "~fox" << std::endl; }
friend fox& make_fox();
chicken& _chicken = licken;
};
eagle eagle1;
fox& make_fox()
{
static fox _fox;
return _fox;
}
auto main() -> int
{
cout << "Hello, World" << endl;
return 0;
}
预期产出:
chicken
fox
eagle
Hello, World
~eagle
~fox
~chicken
答案 1 :(得分:1)
您的答案可以在关于静态初始化顺序惨败的文章中找到(例如this one)。
对于全局变量,初始化(构造函数的调用)在main()
开始之前发生。如果在同一编译单元(.cpp)中有多个全局变量,则初始化以自上而下的顺序发生。如果多个编译单元(.cpp)中有多个全局变量,则初始化顺序未指定(随机)。