1

Possible Duplicate:
Should I pass a shared_ptr by reference?
Passing smart pointers as arguments

Should I pass it by value or by constant reference? I have read numerous rules of thumb on whether to pass a copy constructible object by value or by constant reference. Such as:

  1. pass objects by constant reference and built in types by value (except function objects)
  2. pass by value unless size of the object (including dynamic memory) is less than 2 * size of a double.

Could you explain how do these rules apply to std::shared_ptr<Resource>? I understand that the object is probably very small, likely a pointer and a reference counter, but it is still an object. What is the best practice here?

Community
  • 1
  • 1
Martin Drozdik
  • 12,742
  • 22
  • 81
  • 146
  • 2
    My rules of thumb are: pass by reference when you want reference semantics, and pass by value when you want value semantics. I think they are superior to the ones you've been reading about. (they're also easier to memorize :P) – R. Martinho Fernandes Jul 12 '12 at 06:17
  • @RMartinhoFernandes: how do const references figure into that? The rules of thumb I often read suggest passing by const reference in cases where I'm essentially interested in value semantics (which I take to mean querying an object without changing it) and not reference semantics (where I want the ability to modify the object.) Or were you just stating a tautology: "pass by reference when you want references, pass by value when you want values"? – Managu Jul 12 '12 at 06:25
  • References, whether const or not, provide reference semantics: when variables refer to the same object. Lack of references provides value semantics: when variables refer to different objects. What you described is mutability, which is the criterion for picking const or non-const. – R. Martinho Fernandes Jul 12 '12 at 06:31

1 Answers1

0

Perhaps the most important concern (with regards to performance) is that creating a copy of a std::shared_ptr<...> (such as happens when you pass by value) requires an interlocked increment of a reference count. Or maybe some other form of synchronization like a critical section, depending on implementation. Such a cost could be significant in a multithreaded program.

Passing by reference is almost certain to be a better choice. It's main drawback (or is this only with boost::shared_ptr<...>?) is that shared_ptr<...> offers only the standard thread safety guarantee: access to a single shared_ptr<...> must be guarded (e.g. by a mutex) unless all accesses are only to const methods. In a multithreaded situation, passing around const references to shared_ptr<...>s may make it more difficult to ensure proper synchronization.

In a single threaded program, it probably doesn't make much of a difference.

Managu
  • 8,849
  • 2
  • 30
  • 36
  • I completely disagree that this is the most important concern. The most important concern should be getting a correct program, i.e., whether you want to share ownership or not. – R. Martinho Fernandes Jul 12 '12 at 06:18
  • @RMartinhoFernandes: Good point. I think I meant "the most important concern with regards to performance." Though I know I probably should have just answered "ask your friendly profiler about performance." – Managu Jul 12 '12 at 06:20
  • Anyway, you seem to be arguing passing by reference (leaving aside the question of why someone would even want a reference to a smart pointer) is more performant because, instead of a potentially lock-free operation, you can instead gain a synchronization problem that you can solve with a mutex. Sounds backwards to me. – R. Martinho Fernandes Jul 12 '12 at 06:25
  • @RMartinhoFernandes: Your synopsis is accurate. Lock free operations aren't free of synchronization costs. And I seldom find myself in a situation where I actually need to guard access to a `shared_ptr<...>` -- I just included that for completeness. – Managu Jul 12 '12 at 06:28