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
相关产品推荐
相关产品推荐

