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

如何调用vector<A>中存储的子类对象的重写foo函数?

解决C++中基类容器调用子类重写函数的问题

你碰到的是C++里经典的**对象切片(Object Slicing)**问题——当你把AA/AB这类子类对象直接存入vector<A>时,容器只会拷贝基类A的部分,子类特有的数据和重写的foo()逻辑都被"切掉"了,所以调用时自然只会执行基类的空实现。

要解决这个问题,核心是避免对象切片,同时确保多态机制生效,具体可以按以下步骤来:

关键前提:基类函数必须声明为虚函数

首先要修正基类A的定义,把foo()声明为虚函数——这是C++实现运行时多态的基础,告诉编译器要根据实际对象的类型来调用对应的函数:

class A {
public:
    // 声明为虚函数,允许子类重写
    virtual void foo() {}
    // 基类必须添加虚析构函数,避免通过基类指针删除子类对象时内存泄漏
    virtual ~A() = default;
};

解决方案:使用智能指针容器

不要直接存A类型的对象,改用智能指针(比如std::unique_ptr或std::shared_ptr)来存储指向子类对象的指针,这样既不会发生对象切片,还能自动管理内存,避免手动释放的麻烦。

完整代码示例:

#include <vector>
#include <memory>

class A {
public:
    virtual void foo() {}
    virtual ~A() = default;
};

class AA : public A {
public:
    // 使用override关键字显式标记重写,让编译器帮你检查是否正确重写了基类虚函数
    void foo() override {
        // 子类AA的自定义实现
        // 比如:std::cout << "AA's foo called\n";
    }
};

class AB : public A {
public:
    void foo() override {
        // 子类AB的自定义实现
        // 比如:std::cout << "AB's foo called\n";
    }
};

class C {
private:
    // 存储智能指针的容器,指向A的子类对象
    std::vector<std::unique_ptr<A>> objects;
public:
    // 添加对象的方法,接收unique_ptr并转移所有权
    void addObject(std::unique_ptr<A> obj) {
        objects.push_back(std::move(obj));
    }

    // 遍历容器调用所有对象的foo()
    void callAllFoo() {
        for (auto& ptr : objects) {
            ptr->foo(); // 此时会根据实际子类类型调用对应的foo()
        }
    }
};

// 使用示例
int main() {
    C c;
    // 用make_unique创建子类对象,传入C的容器
    c.addObject(std::make_unique<AA>());
    c.addObject(std::make_unique<AB>());
    c.callAllFoo(); // 会依次执行AA和AB的foo()实现
    return 0;
}

补充说明

  • 如果不想用智能指针,也可以用原始指针,但需要手动管理内存(记得在容器销毁时逐个delete),风险较高,不推荐。
  • 不要尝试用vector<A&>直接存引用——C++的vector不支持存储引用类型,虽然可以用std::reference_wrapper绕开,但需要保证被引用的对象生命周期长于容器,容易出问题,不如智能指针稳妥。

内容的提问来源于stack exchange,提问作者H. Din

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:37:42