我有两个类 A 和 B 使得 A 有一个静态 B 实例作为其成员。B 有一个函数 Show(),这是我的 A 类:
class A
{
A()
{
_b.Show();
}
private:
static B _b;
};
随后的代码是
A a;
B A::_b;
int main()
{
}
现在由于我定义 a 和 _b 的顺序,在构造 B 之前调用了 B::Show()。但是这究竟是如何工作的,即如何才能调用尚未构造的对象?
我有两个类 A 和 B 使得 A 有一个静态 B 实例作为其成员。B 有一个函数 Show(),这是我的 A 类:
class A
{
A()
{
_b.Show();
}
private:
static B _b;
};
随后的代码是
A a;
B A::_b;
int main()
{
}
现在由于我定义 a 和 _b 的顺序,在构造 B 之前调用了 B::Show()。但是这究竟是如何工作的,即如何才能调用尚未构造的对象?
这是不可能的,这是未定义的行为(在这种情况下,因为您正在访问一个未初始化的对象),因为a
在A::_b
.
查找静态初始化命令惨败。您不会收到错误,因为 99% 的情况都会发生这种情况,而且不容易诊断。
这是静态初始化顺序问题。在一般情况下很难解决,但解决某些情况的一种方法是将依赖项放在这样的函数中:
class A
{
public:
A()
{
getB().Show();
}
private:
static B& getB()
{
static B b;
return b;
}
};
函数内的静态变量保证在第一次调用它时被初始化。此外,在 C++11 中,这也保证是线程安全的。
进一步阅读:
http://www.parashift.com/c++-faq/static-init-order-on-first-use.html
怎么可能调用仍未构造的对象?
嗯,简单的答案是,代码就是这样做的。<g>
. 在同一翻译单元的文件范围内定义的对象是按照它们的定义发生的顺序构造的,因此如果一个对象的构造函数依赖于另一个对象,则必须确保在构造函数时已经构造了第二个对象第一个对象运行。
C++ 在这里没有提供任何帮助。你必须自己跟踪它。