Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ unique_ptr argument passing

Suppose I have the following code:

class B { /* */ };

class A {
    vector<B*> vb;
public:
    void add(B* b) { vb.push_back(b); }
};


int main() {

    A a;
    B* b(new B());
    a.add(b);
}

Suppose that in this case, all raw pointers B* can be handled through unique_ptr<B>.

Surprisingly, I wasn't able to find how to convert this code using unique_ptr. After a few tries, I came up with the following code, which compiles:

class A {
    vector<unique_ptr<B>> vb;
public:
    void add(unique_ptr<B> b) { vb.push_back(move(b)); }
};


int main() {

    A a;
    unique_ptr<B> b(new B());
    a.add(move(b));
}

So my simple question: is this the way to do it and in particular, is move(b) the only way to do it? (I was thinking of rvalue references but I don't fully understand them.)

And if you have a link with complete explanations of move semantics, unique_ptr, etc. that I was not able to find, don't hesitate to share it.

EDIT According to http://thbecker.net/articles/rvalue_references/section_01.html, my code seems to be OK.

Actually, std::move is just syntactic sugar. With object x of class X, move(x) is just the same as:

static_cast <X&&>(x)

These 2 move functions are needed because casting to a rvalue reference:

  1. prevents function "add" from passing by value
  2. makes push_back use the default move constructor of B

Apparently, I do not need the second std::move in my main() if I change my "add" function to pass by reference (ordinary lvalue ref).

I would like some confirmation of all this, though...

like image 916
Bérenger Avatar asked Sep 22 '12 20:09

Bérenger


People also ask

Can you pass unique_ptr?

A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.

What happens when you return a unique_ptr?

If a function returns a std::unique_ptr<> , that means the caller takes ownership of the returned object. class Base { ... }; class Derived : public Base { ... }; // Foo takes ownership of |base|, and the caller takes ownership of the returned // object.

What happens when unique_ptr goes out of scope?

An​ unique_ptr has exclusive ownership of the object it points to and ​will destroy the object when the pointer goes out of scope.

What does unique_ptr get do?

unique_ptr::getReturns a pointer to the managed object or nullptr if no object is owned.


1 Answers

Yes, this is how it should be done. You are explicitly transferring ownership from main to A. This is basically the same as your previous code, except it's more explicit and vastly more reliable.

like image 101
Puppy Avatar answered Oct 05 '22 12:10

Puppy