# Another smart_ptr question - pass by value or ref?

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

## Recommended Posts

Hi, Perhaps you could enlighten me? Which is more efficient?
// obj is an object with many datamembers, costly to perform a copy when passing by value
boost::shared_ptr<bigObject> obj( new bigObject );

// Is this the same cost as using bigObject* as a function argument, ie passing by Pointer
void funcPassByValueOfPointer( boost::shared_ptr<bigObject> b );

// does this make sense or pointless?
void funcPassByRef( boost::shared_ptr<bigObject>& b);


Or do i need to use boost::ref, and how is that implemented? Thanks S

##### Share on other sites
Passing by value is marginally slower than passing by reference. Pass your non-basic types by constant reference instead of value wherever possible.

##### Share on other sites
Surely when passing by value, large objects are much slower by value than by ref-to-const since they invoke the implicit copy constructor, replicating the object and every datamember.

However, passing a pointer is as fast as passing by ref since only the address is passed, so is this also the case with smart pointers?

I imagine they are a little slower than normal pointers, since they have the reference count to increment.

##### Share on other sites
Quote:
 Original post by sipicklesI imagine they are a little slower than normal pointers, since they have the reference count to increment.

Bingo.

##### Share on other sites
Where would boost::ref have an application, out of interest?

##### Share on other sites
The point of boost::ref is pretty well explained in the documentation:
Quote:
 Boost.RefThe purpose of boost::reference_wrapper is to contain a reference to an object of type T. It is primarily used to "feed" references to function templates (algorithms) that take their parameter by value.To support this usage, boost::reference_wrapper provides an implicit conversion to T&. This usually allows the function templates to work on references unmodified.

##### Share on other sites
Do you really need access to the smart-pointer? Why not pass a reference of the contained object instead?

void funcPassByRefOfObject(const bigObject& b);boost::shared_ptr<bigObject> obj(new bigObject);funcPassByRefOfObject(*obj)

[Edited by - dalleboy on January 5, 2008 4:17:42 AM]

##### Share on other sites
That entails "trusting" the function that's being called. The definition of "trust" is that someone is able to screw the pooch; in this case, by taking the address of your reference and storing it somewhere.
I would argue that unless this is really time critical, it's better (at least by virtue of being less potentially confusing) to pass the smart pointer by value.

##### Share on other sites
Quote:
 Original post by Jan WassenbergI would argue that unless this is really time critical, it's better (at least by virtue of being less potentially confusing) to pass the smart pointer by value.

This would imply that you have control over the function's signature. And if you do, then it's preferable to use a 'passing style' which correctly represents ownership:
• By shared-pointer when the ownership is shared by both the caller and the called function.
• By reference when the caller keeps exclusive ownership.
• By auto-pointer when the called function receives exclusive ownership.

##### Share on other sites
boost::shared_ptr is uaually also 4 bytes larger than a regular pointer, so that may be something to take into consideration.

##### Share on other sites
Quote:
 Original post by Sc4Freakboost::shared_ptr is uaually also 4 bytes larger than a regular pointer, so that may be something to take into consideration.

Small enough for me - Thanks

##### Share on other sites
From nitpick land:

void funcPassByRef( const boost::shared_ptr<bigObject>& b);

Would make even more sense.

##### Share on other sites
Quote:
 This would imply that you have control over the function's signature. And if you do, then it's preferable to use a 'passing style' which correctly represents ownership:

That sounds reasonable if you're the sole developer in a smallish project, but looks to break down under real-world maintenance.
It's unlikely that every corner of the codebase uses these semantics, so the rule may not be clear to junior coders. What's to prevent them from taking the address and storing it? Writing a "if you use & on this parameter, you will be shot/fired" comment in all of these spots would be tiresome. Sure, they could still store ptr.get(), but at least those spots can be found, unlike operator&.

• 45
• 11
• 17
• 11
• 13