能否将派生类的this指针传递给基类构造函数?是否为未定义行为?
问题解答
你的修改后的代码属于未定义行为(UB),原因如下:
虚函数解析与对象构造阶段限制
派生类对象构造时,会先执行基类构造函数。此时派生类的成员变量尚未初始化,对象的动态类型被视为基类类型。哪怕你把派生类的this指针传给基类构造函数,在基类构造期间调用该指针的虚函数,C++标准规定会解析为基类版本的虚函数——而你的基类中init是纯虚函数,没有具体实现,调用纯虚函数本身就属于未定义行为。派生类未完成构造的潜在风险
就算init不是纯虚函数,在基类构造阶段调用派生类的虚函数也极度危险:如果init中访问了派生类的成员变量,此时这些变量还未初始化,会导致对未定义内存的读写,同样触发未定义行为。
你当前代码运行没崩溃只是偶然情况,未定义行为的表现完全不可预测,换个编译器、平台或者代码场景,就可能出现崩溃、数据损坏等问题。
正确的替代方案
通常可以采用两步初始化或者工厂函数来规避这个问题:
方案1:两步初始化
class A { public: A() = default; virtual void init(someType) = 0; }; class B : public A { public: B() = default; void init(someType someData) override { // 这里写原本要放在init里的初始化逻辑 } }; // 使用方式 B b; b.init(someData);
方案2:工厂函数
#include <memory> class A { public: virtual ~A() = default; virtual void init(someType) = 0; }; class B : public A { public: B() = default; void init(someType someData) override { // 初始化逻辑 } }; std::unique_ptr<A> createB(someType someData) { auto b = std::make_unique<B>(); b->init(someData); return b; }
内容的提问来源于stack exchange,提问作者Reverent Lapwing
相关产品推荐
相关产品推荐

