C++ 子类实例赋值给父类变量后无法调用虚函数重写版本如何解决
问题根因
你当前代码里B test = C();的写法触发了对象切片:当你直接将派生类实例赋值给基类的栈对象时,派生类中不属于基类的部分(包括C类的虚表指针、独有成员)会被截断丢弃,最终test本质是一个纯B类实例,虚函数调用自然只会走到A的实现。
解决方案
要保留多态特性,必须通过基类指针或者基类引用来持有派生类实例,不能直接用基类值类型存储。
方案1:使用基类指针
你可以用普通指针或者智能指针来持有实例,避免对象切片,示例代码如下:
#include <iostream> // 智能指针需要引入的头文件 #include <memory> class A { public: A(/* args */){}; virtual void p(){std::cout << "A\n";} // 存在继承关系的基类建议添加虚析构函数,避免内存泄漏 virtual ~A() = default; }; class B : public A { public: B(/* args */){}; }; class C : public B { public: C(/* args */){}; void p() override{std::cout << "C\n";} }; int main(int argc, char const *argv[]) { // 智能指针写法,无需手动释放内存 std::unique_ptr<B> test = std::make_unique<C>(); // 普通指针写法:B* test = new C(); C test2 = C(); test->p(); test2.p(); // 普通指针需要手动释放内存:delete test; return 0; }
方案2:使用基类引用
如果派生类实例的生命周期和引用的作用域一致,也可以用基类引用绑定派生类实例:
int main(int argc, char const *argv[]) { C c_inst; B& test = c_inst; C test2 = C(); test.p(); test2.p(); return 0; }
两种方案修改后运行输出均为:
C C
符合你的需求。
内容的提问来源于stack exchange,提问作者Jonathan Layduhur
相关产品推荐
相关产品推荐

