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

动态绑定与虚函数:存储Base类对象的vector为何无法调用正确成员函数

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

你遇到的是C++中非常典型的对象切片现象,核心原因是std::vector<Base>存储的是基类对象实例,而非指针或引用,不满足多态的触发条件。


具体原理

C++的多态(虚函数动态派发)生效有两个必要前提:

  • 通过指针或引用调用虚函数
  • 指针/引用指向的是完整的派生类实例,对象本身的虚表指针是派生类对应的版本

std::vector<Base>的每个元素内存大小固定为Base类的大小,当你将Derived类型的d存入vector时,会自动调用Base的拷贝构造函数,只拷贝d中属于Base类的成员部分,Derived类特有的成员、以及Derived类的虚表指针信息都会被截断丢弃,最终存入vector的本质就是一个纯Base类对象,自然只会调用Base的print函数。

对比你之前写的Base* p2 = &d的场景:指针本身只占固定大小的内存,指向的是完整的Derived实例内存,对象的虚表指针还是Derived类的版本,所以调用虚函数可以触发多态。


修复方案

如果要在容器中使用多态,需要存储基类的指针或智能指针:

方案1:存储裸指针

std::vector<Base*> v {&b, &d};
v[1]->print(); // 输出Derived

注意需要手动保证容器内指针指向的对象生命周期长于容器,避免出现野指针。

方案2:存储智能指针(更安全,无需手动管理内存)

#include <memory>
// ...
std::vector<std::unique_ptr<Base>> v;
v.push_back(std::make_unique<Base>());
v.push_back(std::make_unique<Derived>());
v[1]->print(); // 输出Derived

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:06:02