
Whoa! ... This isn't how shared pointers works. You want:
shared_ptr< Session > sp_Session = shared_ptr< Session >( new Session );
No, I don't, actually. I have stated what I am doing. What I have not stated is *why* I am doing it. I have deliberately not stated that because I didn't want the discussion to go off on a tangent. There is nothing wrong with having a dynamically allocated shared_ptr, and no more or less wrong than having a dynamically allocated string or vector or map. My shared_ptr is within a wrapper class and you are basically implying that the only way I can use the shared_ptr is via composition, not aggregation. I will agree that composition is the preferred approach, but I can't do that, so my pseudo-code reflects that. So at the risk of complicating the discussion even further, the reason I *must* use aggregation is because the code in question is part of a hybrid C++/CLI (.NET) implementation. A C++/CLI class *cannot* use composition of a native type such as shared_ptr. So I *must* use aggregation - that's just the way it is. But my question is about boost::shared_ptr, and the context I am using it is irrelevant to my question So, having now let the cat out of the bag, here's the problem domain. My .NET C++/CLI classes, which are garbage-collected, managed classes, have ownership of native, unmanaged classes. I have three native classes A, B, C, and three corresponding garbage-collected classes GA, GB, and GC. The garbage-collected classes exist to allow my C++ classes to be used from a .NET application without requiring a full rewrite of the native C++ classes using a .NET language. For the uninitiated, .NET has a concept called a finaliser which exists explicitly to clean up unmanaged resources prior to garbage collection reclaiming the object. Garbage collection is inherently non-deterministic in nature (ie. GC collected object do not have a defined point where they go "out of scope" like conventional C++), but my native classes have a dependency sequence amongst them. In other words, my native objects can be classified as Level 0, Level 1, and Level 2, such that all Level 2 objects must be cleaned up before the Level 1 object on which it depends, and so on. Since I cannot control the order of garbage collection, I must ensure that the native parent objects do not get cleaned up before the child objects. I am using shared_ptr to ensure the native objects are destroyed at the correct time, irrespective of the order in which the garbage-collected objects are destroyed. Also, let's not get too hung up on the pseudo-code. It is *pseudo-code*. It is to illustrate a point. My real code does not pass a reference to a shared_ptr - it actually passes a reference to a containing object which itself "owns" the shared_ptr, and gets it from that object. But there is nothing fundamentally wrong with passing a reference to a shared_ptr. It doesn't "completely defeat the purpose" at all. Why bother constructing/destroying a temporary object? That's just inefficient. I use shared_ptr when I have a situation where I don't know who is going to be the last to clean-up an object, and I genuinely need to share the same object. The purpose of the question is to question the thread-safety aspects of shared_ptr in the context of a simultaneous increment/decrement of the ref counts by two different threads. Nothing more, nothing less.