在基类构造函数中static_cast this至派生类并后续使用是否合法?
基类构造函数中static_cast子类指针的C++合规性疑问
template <class T> class A { public: A() { subclass = static_cast<T*>(this); } virtual void Foo() = 0; protected: T* subclass; }; class C : public A<C> { public: C(int i) : i(i) { } virtual void Foo() { subclass->Bar(); } void Bar() { std::cout << "i is " << i << std::endl; } private: int i; }; int main() { C c(5); c.Foo(); return 0; }
我们在工作代码库中遇到上述场景,针对代码是否符合C++规范产生了激烈争论。这段代码实际运行总能正常工作(只要模板参数和子类类型匹配),但用运行时分析器检测时,会提示static_cast无效——因为将this转换为C*时,C的构造函数还未执行。实际测试中,如果把static_cast换成dynamic_cast,会返回nullptr,程序调用Bar()访问i时直接崩溃。
我直觉认为,static_cast应该总能被dynamic_cast替代而不破坏代码,这说明原代码依赖了编译器相关的未定义行为。但cppreference中有这样的描述:
If the object expression refers or points to is actually a base class subobject of an object of type D, the result refers to the enclosing object of type D.
我的疑问核心是:在类型D的对象构造完成前,它的基类子对象是否属于D类型的对象?或者说这种static_cast操作本身属于未定义行为?我对C++规则的理解深度不足以解答这个问题。
内容的提问来源于stack exchange,提问作者Chiara Coetzee
相关产品推荐
相关产品推荐

