C++函数重写实现:子类对象传入父类参数函数调用子类方法
解决C++子类实例传入父类参数函数时调用子类方法的问题
嗨,我仔细看了你的代码,问题出在**对象切片(Object Slicing)**上——这是C++多态使用中非常常见的一个坑。
问题根源
你的Parent类已经正确把printData声明为虚函数,Child也重写了这个方法,这部分没问题。但问题出在ParentUser::printer的参数传递方式上:
void printer(Parent p); // 传值传递
当你把Child对象按值传给这个函数时,程序会创建一个Parent类型的副本——这个副本只保留了Child对象中属于Parent的部分,子类特有的信息全被“切掉”了。所以调用p.printData()时,只会执行父类的版本,而不是你期望的子类方法。
解决方案:用引用或指针传递参数
要避免对象切片,实现多态调用,你需要通过引用或指针来传递父类类型的参数,这样不会复制对象,而是直接指向原有的Child实例。
方案1:使用引用传递
修改ParentUser.h中的函数声明:
#ifndef UNTITLED_PARENTUSER_H #define UNTITLED_PARENTUSER_H #include "Parent.h" class ParentUser { public: void printer(Parent& p); // 将参数改为父类引用 }; #endif
ParentUser.cpp的实现只需同步修改参数类型(逻辑不变):
#include "ParentUser.h" #include <iostream> void ParentUser::printer(Parent& p) { p.printData(); }
main.cpp的调用代码不需要修改,直接传child即可:
parentUser.printer(child);
方案2:使用指针传递
如果你更习惯用指针,也可以这样修改:ParentUser.h:
#ifndef UNTITLED_PARENTUSER_H #define UNTITLED_PARENTUSER_H #include "Parent.h" class ParentUser { public: void printer(Parent* p); // 参数改为父类指针 }; #endif
ParentUser.cpp的实现需要用箭头运算符调用方法:
#include "ParentUser.h" #include <iostream> void ParentUser::printer(Parent* p) { p->printData(); }
main.cpp中调用时需要传入对象的地址:
parentUser.printer(&child);
为什么这两种方式能生效?
C++的多态机制依赖于虚函数表(vtable),只有当通过指针或引用调用虚函数时,程序才会根据实际对象的类型(这里是Child)去查找对应的虚函数,从而执行子类的方法。传值传递会破坏这个机制,因为复制后的对象已经是纯父类类型了。
内容的提问来源于stack exchange,提问作者Mohamed Adel
相关产品推荐
相关产品推荐

