我有一个类层次结构,我知道给定的类(B)将始终导出到第二个(D)。在B的构造函数中,如果我确定在整个构造完成之前没有人会尝试使用它,那么将this
指针静态地转换为D *是否安全?在我的例子中,我想将对象的引用传递给另一个类(A)。
struct A
{
D & d_;
A(D & d) : d_(d) {}
};
struct D; //forward declaration
struct B
{
A a;
B() : a(std::static_cast<D&>(*this)) {}
};
struct D : public B
{};
这段代码安全吗?
答案 0 :(得分:2)
不,不是。 D的数据成员的构造者还没有运行。
由于D的构造不是构造的,D还没有完全构造,所以从技术上讲,对D的引用应该是无效的。我希望在大多数实现中都没问题,但仍然存在。
我想建议一个更好的机制,但我认为“更好”取决于实际细节。
答案 1 :(得分:2)
我没有发现任何相关信息。我很难找到你的代码在安全的情况下不安全的原因:
struct B
{
A a;
B(D& d) : a(d) {}
};
struct D : public B
{
D() : B(*this) {}
};
但我可能仍然使用我在这里提供的表格。
答案 2 :(得分:0)
@AProgrammer's answer让我意识到,通过将static_cast
指针从派生类传递给基类,可以轻松避免this
。因此,问题归结为this
指针到成员初始化列表中的有效性。
我在C ++标准[12.6.2.7]中找到了以下注释:
[注意:因为 mem-initializer 是在构造函数的范围内计算的,所以
this
指针可以在表达式中使用 mem-initializer 的-list ,用于引用正在初始化的对象。 ]
因此,在member-initializer-list中使用this
是完全有效的,所以我认为所提供的代码是安全的(只要不访问D的成员)。