Using unique_ptr as a method parameter - pros and cons

I noticed that if I have the following:

#include <memory> using namespace std; class Foo { public: Foo(); }; class Wobble { public: void SetWibble( unique_ptr<Foo> foo ) { this->wibble = move( foo ); } // I like returning a ref as it gives control to // the user of my framework over recieving a & or a copy Foo& GetWibble() { return *wibble; } unique_ptr<Foo> wibble; }; int _tmain(int argc, _TCHAR* argv[]) { unique_ptr<Wobble> wobble; unique_ptr<Foo> foo( new Foo() ); // Look here foo->something = ...; foo->something1 = ...; foo->something2 = ...; wobble->SetWibble( move( foo ) ); return 0; } 

... when I declare foo , I have a nice foo object .. and when I move its property to a wobble instance, foo is now empty in the int _tmain .

I really liked this, because I thought that it deletes the memory and clears the pointer from the int _tmain region ... that in my current context there is no need to flash anymore ... In contrast to this:

 // ... void SetWibble( Foo& foo ) { this->wibble = foo; } // ... int _tmain(int argc, _TCHAR* argv[]) { unique_ptr<Wobble> wobble; Foo foo; foo.something = ...; foo.something1 = ...; foo.something2 = ...; wobble->SetWibble( foo ); return 0; } 

which still maintains a reference to this variable inside the scope.

Q:

  • Is this what I said above correctly?
  • I am wondering if there are any advantages over using unique_ptr and not using unique_ptr here, other than the ones I specified?
+5
source share
1 answer

The main difference between the two examples is not the use of std::unique_ptr , but the use of dynamic memory allocation and stack allocation.

It is usually preferable to select objects on the stack. You will avoid the cost of dynamic memory allocation and unnecessary hover (I see no reason not to allocate Wobble on the stack for starters).

If you're just worried about having a variable in your area, perhaps you can highlight the creation of Foo for a separate function:

 Foo createFoo() { Foo foo; foo.something = ...; foo.something1 = ...; foo.something2 = ...; return foo; } int main() { Wobble wobble; wobble.SetWibble(createFoo()); } 

Alternatively, if Foo is movable, you can move it directly rather than moving std::unique_ptr<Foo> :

 int main() { Wobble wobble; Foo foo; foo.something = ...; foo.something1 = ...; foo.something2 = ...; wobble.SetWibble(std::move(foo)); } 

If you do this, you can optimize SetWibble for references to r-value. Even if there is no particular advantage in promoting Foo , it at least documents that the variable should no longer be resolved.

If Foo does not move and is copied expensively, then yes, then there may be a reason for dynamically allocating memory. And yes, if you are going to dynamically allocate memory, it is good practice to manage this memory with std::unique_ptr .

Off-topic:

  • In the first example, be careful with wibble dereferencing in GetWibble . Do you have a guarantee that wibble not null? It could never have been set, or it could have been set explicitly to nullptr This may be a prerequisite for calling GetWibble , but this is an example of how extra pointer loading can add complexity.
  • In your second example, it would be more idiomatic for SetWibble use a constant reference.
0
source

All Articles