考虑一个具有重载构造函数的 Cow 类 牛:牛(int i);
现在我静态分配 牛 myCow(4);
这个非默认构造函数究竟何时运行? 这是一个好的做法还是有任何陷阱?
最佳答案
这取决于静态的范围。
在文件范围内,静态变量在调用 main()
之前的某个时刻被初始化。初始化的顺序未定义,因此您不能依赖它。请注意,出于初始化计时的目的,类的静态成员位于文件范围内。
例如
static X global_x; // initialised before main() is called
如果静态变量是在函数作用域中定义的,则它会在程序第一次访问它时被初始化。是的,这意味着如果该函数从未被调用,则它永远不会被初始化。同样,出于我们的目的,函数、方法和静态方法被同等对待。
例如
X& func()
{
static X my_x; // initialised the first time the program counter gets here
return my_x;
}
用于进一步理解的附录:
同一翻译单元中的文件范围静态数据按顶级城市顺序初始化,因此它们的初始化顺序相对于彼此是可预测的。无法预测翻译单元之间的顺序。
静态对象的销毁严格按照与构造顺序相反的顺序进行,无论是什么。这提供了一定程度的可预测性,并且意味着(例如)函数范围静态可能取决于另一个函数范围静态或文件范围静态的生命周期...假设函数范围静态未被另一个文件初始化-不同翻译单元中的静态范围:-)
演示:
这里有一个小演示来说明初始化和取消初始化顺序。请注意,函数 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
关于c++ 静态分配对象的构造函数何时运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33825037/