Jump to content
  • Advertisement
Sign in to follow this  
cozzie

Passing std::unique_ptr as const ref

This topic is 626 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all,

Since a while I've started to work more with std::unique_ptr, which gives me control on when to construct an object etc.

Now in some cases some class needs a const ref to an object which is created as a std::unique_ptr.

 

I've been searching on how this should be handled, from what I understand, it's perfectly fine/ OK to pass the std::unique_ptr as *myPtr, when a const ref is expected.

 

From practice/ playing around I see that this works.

My question; would you see any cons in doing it this way?

 

Any input is appreciated, like always.

Share this post


Link to post
Share on other sites
Advertisement

Hi all,

Since a while I've started to work more with std::unique_ptr, which gives me control on when to construct an object etc.

Now in some cases some class needs a const ref to an object which is created as a std::unique_ptr.

 

I've been searching on how this should be handled, from what I understand, it's perfectly fine/ OK to pass the std::unique_ptr as *myPtr, when a const ref is expected.

 

From practice/ playing around I see that this works.

My question; would you see any cons in doing it this way?

 

Any input is appreciated, like always.

 

If you are dealing with C api or external libraries you must use the const ref variant.

In design perspectives, it's usually better to pass a unique ptr, because this clerifies the usage of the pointer (which is the goal of smart pointers).

I don't recommend passing regular pointers (or const *) when you clearly has a Unique_ptr.

If you really have to share the memory (In terms of memory owners) then use a shared_ptr instead of passing the raw pointer. 

Share this post


Link to post
Share on other sites
What Zipster said, x10000.

Smart pointers are there to describe ownership semantics; passing around const refs to unique_ptrs doesn't make a huge amount of conceptual sense - the thing you are passing to can't own, so all you are doing it making a meal of the function signature for no good reason.

Even shared pointers are a bit of an iffy case; often just thrown in because people aren't sure when generally correct design can resolve the majority of cases.

If you are't taking ownership of an object then don't pass in smart pointers would be my default setting - there is nothing wrong with a raw pointer when the design calls for it.

Share this post


Link to post
Share on other sites

Thanks guys.

Ownership of the pointer isn't an issue/topic here, so I'll just pass the raw ptr of the unique_ptr to functions where a const ref is expected. I don't want to pass an actual unique_ptr in these cases. For example, I have a IDevice class that has a 'SetRenderTarget' function, which takes a const ref to a IRenderTarget. And when the 'calling' code has a std::unique_ptr for the IRendertarget object, I'll pass *myRT to pass the object to the IDevice function (which expect a const ref).

Share this post


Link to post
Share on other sites

Ownership of the pointer isn't an issue/topic here

It is. That's what Zipster was trying to explain. It is perfectly fine to pass a reference to an unique pointer from a technical point of view. It just isn't 100% "correct" in semantics.
A unique pointer not only manages the resource but also communicates that your intent is there shall be exactly one such pointer which owns the resource. You can move it, but not copy. If you move it, you must do it explicitly, and you thereby communicate to the human reader that you wish to transfer ownership.

When you create a reference, you're cheating. You are creating a "copy" without creating one. The reference is merely an alias with a different name, sure, so technically this is perfectly correct. But it looks like something different.

I don't want to pass an actual unique_ptr in these cases.

You cannot even do that even if you wanted, the class is designed to not allow this (that's the major difference to it's predecessor auto_ptr). You can only move the unique pointer, which however turns the function into a sink.
Now you can be especially devious and create a reference to the unique pointer, and then move the unique pointer to your function. That, too, is perfectly "correct" (until you access the reference). Only just, when the function returns, the unique pointer that your reference aliases will have been destroyed. Good luck trying to debug that, it might even accidentially work for a while.

Long story short: References to smart pointers are not the most awesome idea in the world.

Share this post


Link to post
Share on other sites
So I get that passing references to unique_ptr's isn't very good. But what about passing collections (say a vector) of unique_ptrs? If I have objects stored in a vector as smart pointers, wouldn't it be problematic to have to make a new vector with raw pointers just to pass the vector to a function?

Share this post


Link to post
Share on other sites

I've been searching on how this should be handled, from what I understand, it's perfectly fine/ OK to pass the std::unique_ptr as *myPtr, when a const ref is expected.
 

 

As others already have explained, this is fine. Just as a comment, I use myPtr.get() instead of *myPtr for extra clarity.

Share this post


Link to post
Share on other sites
Just for future reference, when adding .get() in the sample case above, you still have to use * to identify the pointer. So: *myPtr.get()

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!