传递unique_ptr <derived>&amp;接受unique_ptr <base />&amp;

时间:2017-10-01 03:41:36

标签: c++ c++11 move smart-pointers

我需要通过引用一个函数来传递一个指向派生类的唯一指针,该函数接受对基类的唯一指针的引用,如下所示:

#include <memory>

using namespace std;

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

void foo(std::unique_ptr<Base>& d){}

int main()
{
    unique_ptr<Derived> b = make_unique<Derived>();
    foo(b);
}
  1. 为什么这段代码不起作用?我检查了其他帖子,如this one,答案似乎是&#34;因为C ++希望类型完全匹配&#34;,但为什么会这样?我可能创造了什么危险的情况?

  2. 如果我这样做,它会编译:

    void foo(unique_ptr<Base>&& d){}
    foo(move(b));
    

    这是一种合理的方法吗?

2 个答案:

答案 0 :(得分:2)

  

我可能创造什么危险的情况?

想象一下foo的以下实现:

void foo(std::unique_ptr<Base>& d){
    d.reset(new Base);
}

您现在有std::unique_ptr<Derived>指向不属于Derived类型的对象,编译器无法向您发出任何类型的警告。

正如评论中所述,问题的正确解决方案是按值std::unique_ptr<Base>,并在呼叫网站上移动它。

void foo(std::unique_ptr<Base> d) {
    // move d to your list
}

int main() {
    unique_ptr<Derived> b = make_unique<Derived>();
    foo(std::move(b));
}

答案 1 :(得分:0)

从Derived到Base的简单static_cast,以及适当的释放调用(将资源的所有权转移到新创建的指针)应该可以正常工作。

int main()
{
    unique_ptr<Derived> b = make_unique<Derived>();
    std::unique_ptr<Base> basePointer(static_cast<Base*>(b.release()));
    foo(basePointer);
}