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

C++中struct A与B的多态实现问题:存入vector后需输出b

问题分析与解决方案

你的代码核心问题是对象切片:当执行std::make_unique<A>(a)时,即便a实际引用的是B对象,这里会调用A的拷贝构造函数,仅复制B对象中属于基类A的部分,最终生成的是一个纯A类型的对象,因此调用print()时执行的是A的版本,输出"a"。

要在不知道具体类型的前提下实现多态对象的存储,需要给基类添加克隆函数,让派生类自行实现对象复制逻辑。

修改后的代码

#include <iostream>
#include <vector>
#include <memory>

using namespace std;

struct A
{
    virtual void print()
    {
        std::cout << "a\n";
    }
    // 纯虚克隆函数,强制派生类实现
    virtual std::unique_ptr<A> clone() const = 0;
    // 虚析构函数,确保派生类对象能正确析构
    virtual ~A() = default;
};

struct B : public A
{
    void print() override
    {
        std::cout << "b\n";
    }
    // B类的克隆逻辑,返回自身类型的智能指针
    std::unique_ptr<A> clone() const override
    {
        return std::make_unique<B>(*this);
    }
};

void f(A& a)
{   
    std::vector<std::unique_ptr<A>> vecA;
    // 通过克隆函数复制实际类型的对象
    vecA.emplace_back(a.clone());

    vecA[0]->print(); // 现在会输出"b"
}

int main()
{   
    B b;
    f(b);

    return 0;
}

关键说明

  • 基类添加纯虚clone函数,让每个派生类都实现自己的复制逻辑,保证复制出的是实际类型的对象。
  • 基类必须声明虚析构函数,否则当vector销毁智能指针时,只会调用基类的析构函数,可能导致派生类资源泄漏(这是多态类的标准规范)。
  • 调用a.clone()时,会根据a的实际类型(B)执行对应的克隆函数,生成B对象存入vector,从而保留多态特性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:22:49