C++多态场景下派生类可否用指向子类的父类引用构造实例
报错原因
dynamic_cast语法强制要求目标类型必须为指针或引用类型,你代码中目标类型写为值类型Child,不符合语法规则,直接触发编译错误。- 额外注意:
dynamic_cast依赖运行时类型识别(RTTI),要求父类至少定义一个虚函数,否则也无法正常使用。
正确实现方案
你提到的需求本身是可行的,本质是实现派生类的转换构造函数,只要保证父类引用实际绑定的是当前派生类实例即可,有两种常用实现方式:
方式1:指针转换(可自定义错误处理)
#include <stdexcept> class Child : public Parent { public: // 加explicit避免意外隐式转换 explicit Child(const Parent &pr) { const Child* child_ptr = dynamic_cast<const Child*>(&pr); if (child_ptr == nullptr) { // 转换失败处理逻辑,此处以抛异常为例 throw std::invalid_argument("入参引用的实际类型不是Child"); } // 拷贝成员完成赋值 *this = *child_ptr; } };
方式2:引用转换(失败自动抛异常)
#include <typeinfo> class Child : public Parent { public: explicit Child(const Parent &pr) { // 转换失败直接抛出std::bad_cast异常 const Child& child_ref = dynamic_cast<const Child&>(pr); *this = child_ref; } };
注意事项
- 父类必须定义虚析构函数或者其他虚函数,否则RTTI无法工作,
dynamic_cast会编译失败。 - 如果构造函数加了
explicit关键字,初始化时不能使用拷贝初始化语法Child ch1 = pr,要改用直接初始化Child ch1(pr)即可。 - 只有当入参引用实际绑定的是
Child类实例时转换才会成功,如果绑定的是其他子类或父类本身的实例,会触发转换失败逻辑。
内容的提问来源于stack exchange,提问作者Max Popov
相关产品推荐
相关产品推荐

