简体   繁体   中英

Passing unique_ptr<Derived>& to a function accepting unique_ptr<Base>&

I need to pass a unique pointer to a derived class by reference to a function which accepts a reference to a unique pointer to the base class, like here:

#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. Why doesn't this code work? I checked out other posts like this one , and the answer seems to be "because C++ wants the types to match exactly", but why is that? What dangerous situation am I potentially creating?

  2. If I instead do this, it compiles:

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

    Is this a reasonable approach?

What dangerous situation am I potentially creating?

Imagine the following implementation for foo:

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

You now have a std::unique_ptr<Derived> pointing to an object which is not of type Derived , and the compiler couldn't give you any kind of warning about it.

The correct solution to your problem, as explained in the comments, is to take a std::unique_ptr<Base> by value, and move it at the call site.

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));
}

A simple static_cast from Derived to Base, with an appropriate release call (to transfer the ownership of the resource to the newly created pointer) should work fine.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM