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

C++多态:基类vector存子类对象调用虚函数为何输出基类结果?

C++多态调用不符合预期问题排查

问题复现

学习C++多态特性时编写如下测试代码,预期运行输出结果为5,实际运行输出为3,虚函数未按预期调用子类重写的实现:

#include <iostream>
#include <vector>
using namespace std;

class A {
public:
    int x = 3;

    virtual void print() { cout << 3 << endl; }
};

class B : public A {
public:
    int x = 5;

    void print() { cout << 5 << endl; }
};

int main() {
    B b;
    A a;
    vector<A> name1;

    name1.push_back(b);
    name1[0].print();
    cout<< name1[0].x << endl;

    return 0;
}

问题原因

向元素类型为基类A的vector中压入子类B的对象时,会发生对象切割(Object Slicing):

  • 压入元素的拷贝过程仅会保留子类实例中属于基类A的成员部分,子类B独有的成员(包括子类定义的x变量、虚函数表中对应子类重写方法的条目)会被完全截断丢弃
  • 容器内存储的元素本质是独立的基类A对象,不包含任何子类相关信息,虚函数的多态分发机制自然无法生效,调用方法、访问成员都会走基类A的逻辑。

修复方案

将vector的元素类型修改为基类指针类型,存储对象的内存地址而非直接存储对象实例,从根源上避免对象拷贝带来的切割问题:

  • 容器定义修改为:vector<A*> name1;
  • 压入元素时传入子类对象的地址:name1.push_back(&b);

修改后再次运行代码,虚函数会正确触发动态绑定,调用子类B重写的print()方法,输出符合预期的5。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:48:19