C++ vector存储父类对象时如何调用子类重写的成员函数
问题原因
- 对象切片问题:你声明的
vector<ParentClass>存储的是父类实体对象,当你把子类实例newchild插入容器时,会触发父类的拷贝构造函数,仅拷贝子类中继承自父类的成员,子类独有的特性会被完全截断,容器中存储的实际是父类对象,不可能调用到子类的实现。 - 未声明虚函数:C++的运行时多态要求基类中需要被子类重写的成员函数必须用
virtual关键字修饰,否则编译器会根据变量的静态类型直接绑定函数实现,不会在运行时动态查找子类的重写版本。
修复方案
调整两处代码即可实现预期效果:
- 给基类
ParentClass的print_a函数添加virtual修饰,同时补充虚析构函数避免后续可能出现的内存泄漏问题 - 将vector的存储类型改为父类指针(推荐使用智能指针避免手动管理内存的隐患),存储对象的地址而非拷贝实体
修复后完整代码
#include <iostream> #include <vector> #include <memory> using namespace std; class ParentClass { public: int _a; ParentClass(int a) { this->_a = a; } // 声明为虚函数 virtual void print_a() { cout << "parent a: " << this->_a << endl; } // 补充虚析构函数 virtual ~ParentClass() = default; }; class ChildClass: public ParentClass { public: ChildClass(int a) : ParentClass(a) {} // 加override关键字显式标注是重写父类函数 void print_a() override { cout << "child a: " << this->_a << endl; } }; int main(int argc, char const *argv[]) { int x = 5, y = 6; // 改为存储父类智能指针 vector<unique_ptr<ParentClass>> objects; objects.push_back(make_unique<ParentClass>(x)); objects.push_back(make_unique<ChildClass>(y)); for (auto& obj : objects){ obj->print_a(); } return 0; }
运行输出
parent a: 5 child a: 6
完全符合预期输出要求。
内容的提问来源于stack exchange,提问作者Mleendox
相关产品推荐
相关产品推荐

