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

为何调用派生类对象时触发的是基类虚函数?

问题原因:对象切片(Object Slicing)

这种情况几乎可以确定是FooFighter::doSomethingREF的参数采用了按值接收FooChild对象的方式,而非引用或指针传递。当你传入MockFooChild对象时,只会复制基类FooChild的部分数据,派生类的额外成员和虚函数表信息会被“切掉”,调用虚函数时自然只会触发基类的版本。

典型错误代码示例

假设你的代码结构类似这样:

#include <iostream>
using namespace std;

class FooChild {
public:
    virtual void func() { cout << "FooChild::func" << endl; }
};

class MockFooChild : public FooChild {
public:
    void func() override { cout << "MockFooChild::func" << endl; }
};

class FooFighter {
public:
    // 错误:按值传递触发对象切片
    void doSomethingREF(FooChild obj) {
        obj.func(); // 实际调用FooChild::func
    }

    // 正确:引用传递,支持动态绑定
    void doSomethingREF_Correct(FooChild& obj) {
        obj.func(); // 调用MockFooChild::func
    }

    // 正确:指针传递,支持动态绑定
    void doSomethingPTR(FooChild* obj) {
        obj->func(); // 调用MockFooChild::func
    }
};

当调用doSomethingREF(MockFooChild())时,参数会被切片为纯FooChild对象,其虚函数表指向基类,因此执行基类的func。而引用/指针传递不会复制对象,仅传递对象的地址,能正确访问派生类的虚函数表,所以调用行为符合预期。

解决方法

将doSomethingREF的参数改为引用传递(FooChild&),如果不需要修改对象可以用const FooChild&,这样就能避免对象切片,保证虚函数的动态绑定机制生效。


内容的提问来源于stack exchange,提问作者Micheal Jokim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:01:06