如何将派生类的unique_ptr传入接收基类unique_ptr的函数?
问题原因
你遇到的报错本质是两个原因叠加:
std::unique_ptr是独占型智能指针,禁用了拷贝构造和拷贝赋值,直接传递左值obj2会尝试调用已删除的拷贝构造函数,本身就不合法std::unique_ptr<B>和std::unique_ptr<A>是完全独立的两个类型,默认不支持隐式的左值转换,仅在转移所有权的场景下支持派生类到基类的移动转换
可行方案
按你实际的业务场景二选一即可:
场景1:Validate函数不需要取得对象所有权(绝大多数场景)
这种情况完全没必要把参数绑定为unique_ptr类型,直接用基类指针/引用即可,和普通多态用法完全一致:
// 方案1-1:传基类指针,需要自行判空 void Validate(A* obj) { if (obj) obj->execute(); } // 调用写法 Validate(obj2.get()); // 方案1-2:传基类引用,编译期规避空指针风险,更推荐 void Validate(A& obj) { obj.execute(); } // 调用写法 Validate(*obj2);
场景2:Validate函数需要取得对象的所有权
如果函数内部需要接管对象的生命周期,就用std::move转移unique_ptr的所有权,此时支持派生类unique_ptr到基类unique_ptr的隐式转换:
// 函数定义不需要修改 void Validate(std::unique_ptr<A> obj) { obj->execute(); // 对象生命周期随函数内的obj结束 } // 调用时显式转移所有权 std::unique_ptr<B> obj2 = std::make_unique<B>(); Validate(std::move(obj2)); // 注意:调用完成后obj2会被置空,不能再继续使用
注意:使用该方案必须保证基类A声明了虚析构函数,否则对象销毁时只会调用A的析构函数,导致派生类B的资源泄漏。
内容的提问来源于stack exchange,提问作者Victor M
相关产品推荐
相关产品推荐

