如何通过引用多态传递unique_ptr?

问题描述

我有一个纯虚拟类 Base 和一些派生类 ChildA(A/B/C 等):

class Base {
    ...
}

class ChildA : public Base {
    ...
}

我需要对这些子类的所有权进行特定控制,因此我通过工厂函数std::unique_ptr 生成它们。

在它们的创建/设置过程中的某个时刻,我需要以所有派生类通用的方式修改它们(而不是复制或更改所有权),因此我想使用一个接受它们的基类型的函数并参考:

void modifyInstance(std::unique_ptr<Base>& baseInst);

但是当我尝试像这样使用这个函数时:

bool childAFactory(std::unique_ptr<ChildA>& buffer)
{
    buffer = std::make_unique<ChildA>();
    modifyInstance(buffer);
} 

我收到此错误

error: non-const lvalue reference to type 'unique_ptr<Base>' cannot bind to a value of unrelated type 'unique_ptr<ChildA>'

难道不能以这种特殊方式利用多态性吗?我能找到的唯一类似线程是尝试按值传递的地方,在这种情况下,您显然必须使用 std::move() 并放弃所有权。

我希望函数使用一个普通的 Base 指针并使用 unique_ptr::get() 但我还需要能够有条件地重置函数内的指针(因此指针及其内容需要能够被修改,因此通过引用传递 unique_ptr)。

解决方法

我会这样做:

bool modifyInstance(Base* baseInst);

bool childAFactory(std::unique_ptr<ChildA>& buffer)
{
    buffer = std::make_unique<ChildA>();
    if (!modifyInstance(buffer.get()))
        buffer.reset();
}

也就是让工厂对生命周期负责,只在需要销毁对象时从modifyInstance()返回一个错误结果。