将unique_ptr <Derived>转换为unique_ptr <Base>

Dej*_*jan 2 c++ pointers unique-ptr

一个简单的代码

class Base {};
class Derived : Base {};

unique_ptr<Base> Create() {
    unique_ptr<Base> basePtr = make_unique<Derived>(); // compile error
    return basePtr;
}
Run Code Online (Sandbox Code Playgroud)

产生编译错误("没有合适的转换").我找到了类似的问题,解决方案的用途std::move.我试过这个

unique_ptr<Derived> derived = make_unique<Derived>();
unique_ptr<Base> basePtr = std::move(derived); // compile error
Run Code Online (Sandbox Code Playgroud)

但现在std::move产生编译错误.我还发现问题在哪里(如果我理解的话),如果我们使用,演员应该是自动的

unique_ptr<Base> basePtr = make_unique<Derived>(new Derived()); //compile error
Run Code Online (Sandbox Code Playgroud)

但这也不起作用(编译错误),也不建议使用new智能指针.

什么是正确的解决方案?

到目前为止我找到的唯一可行解决方案

unique_ptr<Base> basePtr = unique_ptr<Base>((Base*)new Derived());
Run Code Online (Sandbox Code Playgroud)

看起来真的很难看.

chr*_*ris 14

您的类是从基类私下继承的.这是默认值class,而默认值struct是公共继承.这使得外部派生到基础的转换无效.unique_ptr使用公共继承处理派生到基本的转换(实例):

 class Base {};
 class Derived : public Base {};
                 ^^^^^^
Run Code Online (Sandbox Code Playgroud)

如下所述,在使用时向基类添加虚拟析构函数也很重要unique_ptr,因为多态破坏依赖于此来定义良好的行为.shared_ptr不会要求这个,但那是偏离主题的.

  • Chris,可能值得将虚拟析构函数添加到 Base 中。就目前情况而言,这将导致上述用例中的 UB,因为 Derived 不会被正确破坏。 (2认同)