为何调用派生类对象时触发的是基类虚函数?
问题原因:对象切片(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
相关产品推荐
相关产品推荐

