You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:07:24