以下示例在12.7 / 3 N3797中给出
struct A { };
struct B : virtual A { };
struct C : B { };
struct D : virtual A { D(A*); };
struct X { X(A*); };
struct E : C, D, X {
E() : D(this), // undefined: upcast from E* to A*
// might use path E* → D* → A*
// but D is not constructed
// D((C*)this), // defined:
// E* → C* defined because E() has started
// and C* → A* defined because
// C fully constructed
X(this) { // defined: upon construction of X,
// C/B/D/A sublattice is fully constructed
}
};
示例规则:
显式或隐式转换引用的指针(glvalue) 类X的对象指向直接或间接的指针(引用) X的基类B,X的构造和所有的构造 其直接或间接衍生的直接或间接基础 从B开始,这些类的销毁应该 没有完成,否则转换结果未定义 行为。
但请考虑对示例进行一些修改:
struct A { };
struct HD { }; // will be used as a base for D
struct B : virtual A { };
struct C : B { };
struct D : HD, virtual A { D(A*); };
struct X { X(A*); };
struct E : C, D, X {
E() : D(this), // 1. Is there undefined behavior?
// I think, there isn't.
X(this) {
}
};
我认为//1
没有UB,因为我们在调用HD
构造函数之前已经构建了类D(A*)
的基础子对象。也就是说,在D(A *)调用时,D
的构造已经开始。
我的推理是否正确?