Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Factories: how to pass temporary smart pointers to functions. C++

Tags:

I have a class Foo

class Foo; 

a factory returning a pointer to it:

std::unique_ptr<Foo> createFoo();  

and, since I have been told by Herb that a plain function with no special claim on the lifetime of Foo should take plain naked pointers:

void plainf(Foo* f); 

How is my client supposed to correctly do this?

plainF(createFoo()); 

He would not be happy if he had to write:

auto someName = createFoo(); plainF(someName.get());  
like image 825
jimifiki Avatar asked Jun 14 '18 13:06

jimifiki


People also ask

Can you pass a smart pointer to function?

Reason Passing a smart pointer transfers or shares ownership and should only be used when ownership semantics are intended (see R. 30). Passing by smart pointer restricts the use of a function to callers that use smart pointers. Passing a shared smart pointer (e.g., std::shared_ptr) implies a run-time cost.

Can you pass a std :: unique_ptr as a parameter to a function?

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.

Does C ++ 11 have smart pointers?

C++11 includes a solution: "weak" smart pointers: these only "observe" an object but do not influence its lifetime. A ring of objects can point to each other with weak_ptrs, which point to the managed object but do not keep it in existence.


2 Answers

You can use the get member function which returns a raw pointer to the owned object.

plainF(createFoo().get()); 

The temporary created by createFoo() will not go out of scope until plainF has finished. So long as plainF doesn't pass the pointer up out of scope this is completely safe.

like image 197
NathanOliver Avatar answered Sep 22 '22 16:09

NathanOliver


If you don't need the argument to plainF to be nullable, you can also change its signature to take the argument by reference, allowing for a slightly less verbose syntax:

std::unique_ptr<Foo> createFoo();  void plainf(Foo& f);  plainF(*createFoo()); 

All the lifetime considerations mentioned in NathanOliver's answer apply, so this is just as safe to use.

Note that this implies that createFoo will never return an empty unique_ptr. So if that function is allowed to fail, you must indicate that error through other means, eg. by throwing an exception.

like image 26
ComicSansMS Avatar answered Sep 24 '22 16:09

ComicSansMS