[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

ref to shared_ptr?

.rhavin grobert

10/22/2008 3:05:00 PM

are there any pro's and con's in using references to shared_ptr<>'s ?

example:

__________________________________________________
void obj::foo(shared_ptr<>); vs. void obj::foo(shared_ptr<>&);

and

shared_ptr<>& obj::foo2(); vs. shared_ptr<> obj::foo2();
__________________________________________________

....?


TIA, ~.rhavin;)
5 Answers

Maxim Yegorushkin

10/22/2008 3:31:00 PM

0

On Oct 22, 4:04 pm, ".rhavin grobert" <cl...@yahoo.de> wrote:
> are there any pro's and con's in using references to shared_ptr<>'s ?
>
> example:
>
> __________________________________________________
> void obj::foo(shared_ptr<>);   vs.  void obj::foo(shared_ptr<>&);

Passing shared_ptr by value causes a call to shared_ptr's copy
constructor just before the function call and a call to the destructor
upon leaving the function. On the other hand, passing by reference
does not involve any constructor/destructor calls (unless it is a
reference to const bound to a temporary object). It depends on an
application whether the difference is noticeable.

Speaking generally, functions that do not acquire or share the
ownership of passed objects should not be taking any smart pointers,
rather they should accept objects by plain reference/pointer.

> and
>
> shared_ptr<>& obj::foo2();    vs.    shared_ptr<> obj::foo2();

Performance considerations are the same as for passing shared_ptr to
functions.

Again, one should really think about interfaces and ownership. Is it
expected that the callers of obj::foo2() are going to share the
ownership of the object. If not, it is better to return a plain
pointer/reference.

--
Max

Marcel Müller

10/22/2008 3:44:00 PM

0

Hi,

..rhavin grobert schrieb:
> __________________________________________________
> void obj::foo(shared_ptr<>); vs. void obj::foo(shared_ptr<>&);
>
> and
>
> shared_ptr<>& obj::foo2(); vs. shared_ptr<> obj::foo2();
> __________________________________________________

well, in this case it is up to you to ensure the livetime of the
referenced object.

In general returning a reference to a shared_ptr is a bad advice, since
shared_ptr is explicitly designed to manage object lifetime in
situations like this. And the copy constructor of shared_ptr is quite
cheap, since it is always only a reference to your object.

Remember that when returning a reference to a shared_ptr, the pointer
may no longer point to the same object when you dereference it.
Or, if the shared_ptr instance is ownd by exactly one thread, it will
point to the same object, but the object's lifetime will neccessarily
exceed the lifetime of the shared_ptr in this case. So you could in fact
also return an ordinary pointer (or even better a reference) to your
object. This will more clearly show what is going on.

I think there is only one situation where it is siutable to return a
reference to a shared_ptr: if it is intended that the caller modifies
the shared_ptr (not only the object where it points to).


Marcel

Hendrik Schober

10/22/2008 4:32:00 PM

0

Marcel Müller wrote:
> Hi,
>
> ..rhavin grobert schrieb:
>> __________________________________________________
>> void obj::foo(shared_ptr<>); vs. void obj::foo(shared_ptr<>&);
>>
>> and
>>
>> shared_ptr<>& obj::foo2(); vs. shared_ptr<> obj::foo2();
>> __________________________________________________
>
> well, in this case it is up to you to ensure the livetime of the
> referenced object.
>
> In general returning a reference to a shared_ptr is a bad advice, since
> shared_ptr is explicitly designed to manage object lifetime in
> situations like this. And the copy constructor of shared_ptr is quite
> cheap, since it is always only a reference to your object.

That depends. Incrementing/decrementing reference counts
need to be seen by all processors on multi-processors
architectures, so it requires access to the main memory,
rather than to the cache. Depending on what your program
does, that could be quite expensive.
I do, however, agree that, when you pass a const ref to
a smart pointer, you should probably be passing a const
ref to the object instead. (OTOH, I recently modified a
piece of library cod to use smart pointers instead of
dumb ones and did not evaluate all function signatures
for whether passing an object instead of a pointer would
have been better. Instead I passed smart pointers per
const ref where applicable.)

> [...]
> Marcel

Schobi

Paavo Helde

10/22/2008 6:09:00 PM

0

Hendrik Schober <spamtrap@gmx.de> kirjutas:

> Marcel Müller wrote:
>> Hi,
>>
>> ..rhavin grobert schrieb:
>>> __________________________________________________
>>> void obj::foo(shared_ptr<>); vs. void obj::foo(shared_ptr<>&);
>>>
>>> and
>>>
>>> shared_ptr<>& obj::foo2(); vs. shared_ptr<> obj::foo2();
>>> __________________________________________________
>>
>> well, in this case it is up to you to ensure the livetime of the
>> referenced object.
>>
>> In general returning a reference to a shared_ptr is a bad advice,
>> since shared_ptr is explicitly designed to manage object lifetime in
>> situations like this. And the copy constructor of shared_ptr is quite
>> cheap, since it is always only a reference to your object.
>
> That depends. Incrementing/decrementing reference counts
> need to be seen by all processors on multi-processors
> architectures, so it requires access to the main memory,

This holds only for smartpointers supporting multithreaded access.
Depending on the application, it might be more useful to consider some
(most?) objects to belong to a certain thread, and to be accessed in
this thread by single-threaded smartpointers. This approach is more
scalable to many cores as no "world-synchronisation" is required for
each refcount update.

Paavo

Stuart Golodetz

11/1/2008 11:21:00 PM

0

Hendrik Schober wrote:
> Marcel Müller wrote:
>> Hi,
>>
>> ..rhavin grobert schrieb:
>>> __________________________________________________
>>> void obj::foo(shared_ptr<>); vs. void obj::foo(shared_ptr<>&);
>>>
>>> and
>>>
>>> shared_ptr<>& obj::foo2(); vs. shared_ptr<> obj::foo2();
>>> __________________________________________________
>>
>> well, in this case it is up to you to ensure the livetime of the
>> referenced object.
>>
>> In general returning a reference to a shared_ptr is a bad advice,
>> since shared_ptr is explicitly designed to manage object lifetime in
>> situations like this. And the copy constructor of shared_ptr is quite
>> cheap, since it is always only a reference to your object.
>
> That depends. Incrementing/decrementing reference counts
> need to be seen by all processors on multi-processors
> architectures, so it requires access to the main memory,
> rather than to the cache. Depending on what your program
> does, that could be quite expensive.
> I do, however, agree that, when you pass a const ref to
> a smart pointer, you should probably be passing a const
> ref to the object instead.

I guess it depends on what you want to do with the thing you're passing
in. If you're just accessing it, then passing a const ref to the object
makes sense (though arguably no more sense than passing a const ref to
the shared_ptr, if that's what you've got); if you need to store the
object, then passing a const ref to the shared_ptr may be a much better
idea - if you pass a const ref to the object, the only way to store it
is to make a copy, which can be expensive/in some cases (if the copy
constructor is inaccessible) impossible. Copying the shared_ptr, on the
other hand, is generally far less expensive (even if we eschew the
debate about whether or not it is actually 'cheap', for some definition
of cheap).

As a side point, btw, it's worth noting that the const semantics of
passing a const ref to the shared_ptr and a const ref to the object are
different: if you pass a const ref to the shared_ptr, you can change the
object it points to but not the shared_ptr. It's like the distinction
between const X& and X *const. To get the same semantics, you probably want:

const shared_ptr<const X>&

It's also worth noting that there's a conversion:

shared_ptr<X> -> shared_ptr<const X>

So you can pass a shared_ptr<X> to a function which expects a
shared_ptr<const X>.

Stu

> (OTOH, I recently modified a
> piece of library cod to use smart pointers instead of
> dumb ones and did not evaluate all function signatures
> for whether passing an object instead of a pointer would
> have been better. Instead I passed smart pointers per
> const ref where applicable.)
>
>> [...]
>> Marcel
>
> Schobi