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

C++ print函数传入子类对象时virtual虚函数未触发重写问题

问题原因分析

核心问题是发生了对象切片(Object Slicing),以下是完整问题代码:

#include<iostream>

class Entity {
public:
    virtual int get_name() { return 1; }
};

class Player : public Entity {
public:
    int m_Name;
    Player(const int name) {
        m_Name = name;
    }
    int get_name() override { return m_Name; }
};

// 问题出在这个函数的形参定义
void print(Entity entity) {
    std::cout << entity.get_name() << std::endl;
}

int main() {
    Entity e;
    Player p(2);
    print(e);
    print(p);
    std::cin.get();
    return 0;
}

具体原因说明:

  • 你定义的print函数用了值传递的Entity类型作为形参,当传入派生类Player的对象p时,会触发基类Entity的拷贝构造函数,仅拷贝p中属于基类Entity的成员,派生类Player独有的m_Name成员、以及Player的虚函数表信息都会被“切掉”,最终在函数内部得到的entity本质是一个纯Entity类型的对象,和原p对象没有关系。你调试时看到的p.m_Name=2是原对象的数值,不受这次拷贝切片的影响。
  • 因此调用entity.get_name()时,不会触发多态,只会执行Entity类的get_name实现,固定返回1。
  • 如果你把print的形参改成Entity& entity(引用传递)或者Entity* entity(指针传递),就不会发生对象切片,多态机制会正常生效,传入p时就会调用Player的get_name返回2;你改成Player类型的值传递形参时,会完整拷贝整个Player对象,没有切片,自然也能正确返回2。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 03:54:04