Smart pointers: who owns the object? [closed] - c++

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
C++ is all about memory ownership - aka ownership semantics.
It is the responsibility of the owner of a chunk of dynamically allocated memory to release that memory. So the question really becomes who owns the memory.
In C++ ownership is documented by the type a raw pointer is wrapped inside thus in a good (IMO) C++ program it is very rare (rare, not never) to see raw pointers passed around (as raw pointers have no inferred ownership thus we can not tell who owns the memory and thus without careful reading of the documentation you can't tell who is responsible for ownership).
Conversely, it is rare to see raw pointers stored in a class each raw pointer is stored within its own smart pointer wrapper. (N.B.: If you don't own an object you should not be storing it because you can not know when it will go out of scope and be destroyed.)
So the question:
What type of ownership semantic have people come across?
What standard classes are used to implement those semantics?
In what situations do you find them useful?
Lets keep 1 type of semantic ownership per answer so they can be voted up and down individually.
Summary:
Conceptually, smart pointers are simple and a naive implementation is easy. I have seen many attempted implementations, but invariably they are broken in some way that is not obvious to casual use and examples. Thus I recommend always using well tested smart pointers from a library rather than rolling your own. std::auto_ptr or one of the Boost smart pointers seem to cover all my needs.
std::auto_ptr<T>:
Single person owns the object. Transfer of ownership is allowed.
Usage: This allows you to define interfaces that show the explicit transfer of ownership.
boost::scoped_ptr<T>
Single person owns the object. Transfer of ownership is NOT allowed.
Usage: Used to show explicit ownership. Object will be destroyed by destructor or when explicitly reset.
boost::shared_ptr<T> (std::tr1::shared_ptr<T>)
Multiple ownership. This is a simple reference counted pointer. When the reference count reaches zero, the object is destroyed.
Usage: When an object can have multiple owers with a lifetime that can not be determined at compile time.
boost::weak_ptr<T>:
Used with shared_ptr<T> in situations where a cycle of pointers may happen.
Usage: Used to stop cycles from retaining objects when only the cycle is maintaining a shared refcount.

Simple C++ Model
In most modules I saw, by default, it was assumed that receiving pointers was not receiving ownership. In fact, functions/methods abandoning ownership of a pointer were both very rare and explicitly expressed that fact in their documentation.
This model assumes that the user is owner only of what he/she explicitly allocates. Everything else is automatically disposed of (at scope exit, or through RAII). This is a C-like model, extended by the fact most pointers are owned by objects that will deallocate them automatically or when needed (at said objects destruction, mostly), and that the life duration of objects are predictable (RAII is your friend, again).
In this model, raw pointers are freely circulating and mostly not dangerous (but if the developer is smart enough, he/she will use references instead whenever possible).
raw pointers
std::auto_ptr
boost::scoped_ptr
Smart Pointed C++ Model
In a code full of smart pointers, the user can hope to ignore the lifetime of objects. The owner is never the user code: It is the smart pointer itself (RAII, again). The problem is that circular references mixed with reference counted smart pointers can be deadly, so you have to deal both with both shared pointers and weak pointers. So you have still ownership to consider (the weak pointer could well point to nothing, even if its advantage over raw pointer is that it can tell you so).
boost::shared_ptr
boost::weak_ptr
Conclusion
No matter the models I describe, unless exception, receiving a pointer is not receiving its ownership and it is still very important to know who owns who. Even for C++ code heavily using references and/or smart pointers.

For me, these 3 kinds cover most of my needs:
shared_ptr - reference-counted, deallocation when the counter reaches zero
weak_ptr - same as above, but it's a 'slave' for a shared_ptr, can't deallocate
auto_ptr - when the creation and deallocation happen inside the same function, or when the object has to be considered one-owner-only ever. When you assign one pointer to another, the second 'steals' the object from the first.
I have my own implementation for these, but they are also available in Boost.
I still pass objects by reference (const whenever possible), in this case the called method must assume the object is alive only during the time of call.
There's another kind of pointer that I use that I call hub_ptr. It's when you have an object that must be accessible from objects nested in it (usually as a virtual base class). This could be solved by passing a weak_ptr to them, but it doesn't have a shared_ptr to itself. As it knows these objects wouldn't live longer than him, it passes a hub_ptr to them (it's just a template wrapper to a regular pointer).

Don't have shared ownership. If you do, make sure it's only with code you don't control.
That solves 100% of the problems, since it forces you to understand how everything interacts.

Shared Ownership
boost::shared_ptr
When a resource is shared between multiple objects.
The boost shared_ptr uses reference counting to make sure the resource is de-allocated when everybody is finsihed.

std::tr1::shared_ptr<Blah> is quite often your best bet.

From boost, there's also the pointer container library. These are a bit more efficient and easier to use than a standard container of smart pointers, if you'll only be using the objects in the context of their container.
On Windows, there are the COM pointers (IUnknown, IDispatch, and friends), and various smart pointers for handling them (e.g. the ATL's CComPtr and the smart pointers auto-generated by the "import" statement in Visual Studio based on the _com_ptr class).

One Owner
boost::scoped_ptr
When you need to allocate memory dynamically but want to be sure it gets deallocated on every exit point of the block.
I find this usefull as it can easily be reseated, and released without ever having to worry about a leak

I don't think I ever was in a position to have shared ownership in my design. In fact, from the top of my head the only valid case I can think of is Flyweight pattern.

yasper::ptr is a lightweight, boost::shared_ptr like alternative. It works well in my (for now) small project.
In the web page at http://yasper.sourceforge.net/ it's described as follows:
Why write another C++ smart pointer?
There already exist several high
quality smart pointer implementations
for C++, most prominently the Boost
pointer pantheon and Loki's SmartPtr.
For a good comparison of smart pointer
implementations and when their use is
appropriate please read Herb Sutter's
The New C++: Smart(er) Pointers. In
contrast with the expansive features
of other libraries, Yasper is a
narrowly focused reference counting
pointer. It corresponds closely with
Boost's shared_ptr and Loki's
RefCounted/AllowConversion policies.
Yasper allows C++ programmers to
forget about memory management without
introducing the Boost's large
dependencies or having to learn about
Loki's complicated policy templates.
Philosophy
* small (contained in single header)
* simple (nothing fancy in the code, easy to understand)
* maximum compatibility (drop in replacement for dumb pointers)
The last point can be dangerous, since
yasper permits risky (yet useful)
actions (such as assignment to raw
pointers and manual release)
disallowed by other implementations.
Be careful, only use those features if
you know what you're doing!

There is another frequently used form of single-transferable-owner, and it is preferable to auto_ptr because it avoids the problems caused by auto_ptr's insane corruption of assignment semantics.
I speak of none other than swap. Any type with a suitable swap function can be conceived of as a smart reference to some content, which it owns until such time as ownership is transferred to another instance of the same type, by swapping them. Each instance retains its identity but gets bound to new content. It's like a safely rebindable reference.
(It's a smart reference rather than a smart pointer because you don't have to explicitly dereference it to get at the content.)
This means that auto_ptr becomes less necessary - it's only needed to fill the gaps where types don't have a good swap function. But all std containers do.

One Owner: Aka delete on Copy
std::auto_ptr
When the creator of the object wants to explicitly hand ownership to somebody else.
This is also a way documenting in the code I am giving this to you and I am no longer tracking it so make sure you delete it when you are finished.

Related

STL smart pointers vs Qt smart pointers? [duplicate]

Comparisons, Pros, Cons, and When to Use?
This is a spin-off from a garbage collection thread where what I thought was a simple answer generated a lot of comments about some specific smart pointer implementations so it seemed worth starting a new post.
Ultimately the question is what are the various implementations of smart pointers in C++ out there and how do they compare? Just simple pros and cons or exceptions and gotchas to something you might otherwise think should work.
I've posted some implementations that I've used or at least glossed over and considered using as an answer below and my understanding of their differences and similarities which may not be 100% accurate so feel free to fact check or correct me as needed.
The goal is to learn about some new objects and libraries or correct my usage and understanding of existing implementations already widely in use and end up with a decent reference for others.
C++03
std::auto_ptr - Perhaps one of the originals it suffered from first draft syndrome only providing limited garbage collection facilities. The first downside being that it calls delete upon destruction making them unacceptable for holding array allocated objects (new[]). It takes ownership of the pointer so two auto pointers shouldn't contain the same object. Assignment will transfer ownership and reset the rvalue auto pointer to a null pointer. Which leads to perhaps the worst drawback; they can't be used within STL containers due to the aforementioned inability to be copied. The final blow to any use case is they are slated to be deprecated in the next standard of C++.
std::auto_ptr_ref - This is not a smart pointer it's actually a design detail used in conjunction with std::auto_ptr to allow copying and assignment in certain situations. Specifically it can be used to convert a non-const std::auto_ptr to an lvalue using the Colvin-Gibbons trick also known as a move constructor to transfer ownership.
On the contrary perhaps std::auto_ptr wasn't really intended to be used as a general purpose smart pointer for automatic garbage collection. Most of my limited understanding and assumptions are based on Herb Sutter's Effective Use of auto_ptr and I do use it regularly although not always in the most optimized way.
C++11
std::unique_ptr - This is our friend who will be replacing std::auto_ptr it will be quite similar except with the key improvements to correct the weaknesses of std::auto_ptr like working with arrays, lvalue protection via private copy constructor, being usable with STL containers and algorithms, etc. Since it's performance overhead and memory footprint are limited this is an ideal candidate for replacing, or perhaps more aptly described as owning, raw pointers. As the "unique" implies there is only one owner of the pointer just like the previous std::auto_ptr.
std::shared_ptr - I believe this is based off TR1 and boost::shared_ptr but improved to include aliasing and pointer arithmetic as well. In short it wraps a reference counted smart pointer around a dynamically allocated object. As the "shared" implies the pointer can be owned by more than one shared pointer when the last reference of the last shared pointer goes out of scope then the object will be deleted appropriately. These are also thread safe and can handle incomplete types in most cases. std::make_shared can be used to efficiently construct a std::shared_ptr with one heap allocation using the default allocator.
std::weak_ptr - Likewise based off TR1 and boost::weak_ptr. This is a reference to an object owned by a std::shared_ptr and will therefore not prevent the deletion of the object if the std::shared_ptr reference count drops to zero. In order to get access to the raw pointer you'll first need to access the std::shared_ptr by calling lock which will return an empty std::shared_ptr if the owned pointer has expired and been destroyed already. This is primarily useful to avoid indefinite hanging reference counts when using multiple smart pointers.
Boost
boost::shared_ptr - Probably the easiest to use in the most varying scenarios (STL, PIMPL, RAII, etc) this is a shared referenced counted smart pointer. I've heard a few complaints about performance and overhead in some situations but I must have ignored them because I can't remember what the argument was. Apparently it was popular enough to become a pending standard C++ object and no drawbacks over the norm regarding smart pointers come to mind.
boost::weak_ptr - Much like previous description of std::weak_ptr, based on this implementation, this allows a non-owning reference to a boost::shared_ptr. You not surprisingly call lock() to access the "strong" shared pointer and must check to make sure it's valid as it could have already been destroyed. Just make sure not to store the shared pointer returned and let it go out of scope as soon as you're done with it otherwise you're right back to the cyclic reference problem where your reference counts will hang and objects will not be destroyed.
boost::scoped_ptr - This is a simple smart pointer class with little overhead probably designed for a better performing alternative to boost::shared_ptr when usable. It's comparable to std::auto_ptr especially in the fact that it can't be safely used as an element of a STL container or with multiple pointers to the same object.
boost::intrusive_ptr - I've never used this but from my understanding it's designed to be used when creating your own smart pointer compatible classes. You need to implement the reference counting yourself, you'll also need to implement a few methods if you want your class to be generic, furthermore you'd have to implement your own thread safety. On the plus side this probably gives you the most custom way of picking and choosing exactly how much or how little "smartness" you want. intrusive_ptr is typically more efficient than shared_ptr since it allows you to have a single heap allocation per object. (thanks Arvid)
boost::shared_array - This is a boost::shared_ptr for arrays. Basically new [], operator[], and of course delete [] are baked in. This can be used in STL containers and as far as I know does everything boost:shared_ptr does although you can't use boost::weak_ptr with these. You could however alternatively use a boost::shared_ptr<std::vector<>> for similar functionality and to regain the ability to use boost::weak_ptr for references.
boost::scoped_array - This is a boost::scoped_ptr for arrays. As with boost::shared_array all the necessary array goodness is baked in. This one is non-copyable and so can't be used in STL containers. I've found almost anywhere you find yourself wanting to use this you probably could just use std::vector. I've never determined which is actually faster or has less overhead but this scoped array seems far less involved than a STL vector. When you want to keep allocation on the stack consider boost::array instead.
Qt
QPointer - Introduced in Qt 4.0 this is a "weak" smart pointer which only works with QObject and derived classes, which in the Qt framework is almost everything so that's not really a limitation. However there are limitations namely that it doesn't supply a "strong" pointer and although you can check if the underlying object is valid with isNull() you could find your object being destroyed right after you pass that check especially in multi-threaded environments. Qt people consider this deprecated I believe.
QSharedDataPointer - This is a "strong" smart pointer potentially comparable to boost::intrusive_ptr although it has some built in thread safety but it does require you to include reference counting methods (ref and deref) which you can do by subclassing QSharedData. As with much of Qt the objects are best used through ample inheritance and subclassing everything seems to be the intended design.
QExplicitlySharedDataPointer - Very similar to QSharedDataPointer except it doesn't implicitly call detach(). I'd call this version 2.0 of QSharedDataPointer as that slight increase in control as to exactly when to detach after the reference count drops to zero isn't particularly worth a whole new object.
QSharedPointer - Atomic reference counting, thread safe, sharable pointer, custom deletes (array support), sounds like everything a smart pointer should be. This is what I primarily use as a smart pointer in Qt and I find it comparable with boost:shared_ptr although probably significantly more overhead like many objects in Qt.
QWeakPointer - Do you sense a reoccurring pattern? Just as std::weak_ptr and boost::weak_ptr this is used in conjunction with QSharedPointer when you need references between two smart pointers that would otherwise cause your objects to never be deleted.
QScopedPointer - This name should also look familiar and actually was in fact based on boost::scoped_ptr unlike the Qt versions of shared and weak pointers. It functions to provide a single owner smart pointer without the overhead of QSharedPointer which makes it more suitable for compatibility, exception safe code, and all the things you might use std::auto_ptr or boost::scoped_ptr for.
There is also Loki which implements policy-based smart pointers.
Other references on policy-based smart pointers, addressing the problem of the poor support of the empty base optimization along with multiple inheritance by many compilers:
Smart Pointers Reloaded
A Proposal to Add a Policy-Based Smart Pointer Framework to the Standard Library
In addition to the ones given, there are some safety oriented ones too:
SaferCPlusPlus
mse::TRefCountingPointer is a reference counting smart pointer like std::shared_ptr. The difference being that mse::TRefCountingPointer is safer, smaller and faster, but does not have any thread safety mechanism. And it comes in "not null" and "fixed" (non-retargetable) versions that can be safely assumed to always be pointing to a validly allocated object. So basically, if your target object is shared among asynchronous threads then use std::shared_ptr, otherwise mse::TRefCountingPointer is more optimal.
mse::TScopeOwnerPointer is similar to boost::scoped_ptr, but works in conjunction with mse::TScopeFixedPointer in a "strong-weak" pointer relationship kind of like std::shared_ptr and std::weak_ptr.
mse::TScopeFixedPointer points to objects that are allocated on the stack, or whose "owning" pointer is allocated on the stack. It is (intentionally) limited in it's functionality to enhance compile-time safety with no runtime cost. The point of "scope" pointers is essentially to identify a set of circumstances that are simple and deterministic enough that no (runtime) safety mechanisms are necessary.
mse::TRegisteredPointer behaves like a raw pointer, except that its value is automatically set to null_ptr when the target object is destroyed. It can be used as a general replacement for raw pointers in most situations. Like a raw pointer, it does not have any intrinsic thread safety. But in exchange it has no problem targeting objects allocated on the stack (and obtaining the corresponding performance benefit). When run-time checks are enabled, this pointer is safe from accessing invalid memory. Because mse::TRegisteredPointer has the same behavior as a raw pointer when pointing to valid objects, it can be "disabled" (automatically replaced with the corresponding raw pointer) with a compile-time directive, allowing it to be used to help catch bugs in debug/test/beta modes while incurring no overhead cost in release mode.
Here is an article describing why and how to use them. (Note, shameless plug.)

How efficient smart pointers are?

I know, that std::shared_ptr uses reference counting, so it has copy&move semantics, on the other hand std::unique_ptr (hence the name unique) only has move semantics, so trying to copy it is a compile error.
However, its not quite clear for me how big of a deal is that. Can I simply use std::shared_ptr over std::unique_ptr in most cases, or should I use std::unique_ptr whenever possible, as it's far more efficient because it doesn't have to take care of reference counting?
Also, I know that smart pointers are useful when dealing with, for example exception safety, but are they a mean to generally replace traditional T* pointers?
Is it a good programming practice to use smart pointers over traditional T* pointers whenever possible?
The rule of thumb is:
If you can, use a stack based object directly or by a reference instead of using pointers.
Else, if you don't have to deal with shared ownership (usually you don't) use unique_ptr - it is not only faster, but also safer (no circular references).
Else, if you do have shared ownership, use shared_ptr
Raw pointers are OK in certain circumstances when they don't carry ownership - for instance as an input argument to a function:
void draw (const shape* sh) {
sh->draw();
}
...
std::unique_ptr<shape> ptr(new triangle);
draw(ptr.get());
The problem with the shared_ptr is, that, afaik, the reference counting is an atomic function, that means it not only counts the references, but also has locking functionality to ensure that the function is atomic. So at that point, yes, unique_ptr is better to use, when you only need move functionality.
Personally, I dont use shared_ptr alot, mostly normal pointers are enough. Imho smart pointers are only encourage getting lazy in memory management. I was in projects where smart pointers only caused race conditions when quitting the program, because nobody knew the order of destruction and these pointers referenced each others. For myself, I only use them if a lib of mine is putting pointers to the outside for which it is irrelevent when they get deleted (or in which order).
You should prefer values to std::unique_ptr, and std::unique_ptr to std::shared_ptr whenever possible, but not for performance reasons. Yes, there is some overhead when it comes to std::shared_ptr, as they use inside some form of atomic counter, but this is negligible for most applications.
The main reason to use std::unique_ptr is the uniqueness semantics - when you (or someone else) read(s) the code it's very clear the lifetime and the ownership of the object. This makes it more easy to reason about the code and find logical/performance issues.
PS: std::unique_ptr has no overhead compared to raw pointer, but it has some great advantages.
A shared_ptr has the extra cost of construction/destruction of the pointer itself, if passed to a function, plus the reference counting mechanism.
Do not listen to anyone that says either smart pointers are always the way to go, nor to people who say raw pointers are always better.
There are cases where smart pointers make sense, and cases where raw pointers are preferable.
For a more detailed and comprehensive read, I'll suggest you to visit:
http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
It covers all the points you raised and it is an easy read for the most part.
shared_ptr means that the ownership rules surrounding the resource are complicated. Understanding them requires tracking down the lifetime of all shared_ptrs in the general case.
unique_ptr means that the ownership rules surrounding the resource are dead easy.
Both enforce a set of ownership rules, but the rules for unique_ptr are simple and local, the rules for shared_ptr are complex and non-local. If you are in a situation where you are choosing between the two casually, then you aren't treating lifetime issues with the gravity they deserve.
If you have a pointer-like resource whose lifetime should be controlled simply, or even at some central location (type-wise) with complex logic around it, use unique_ptr. The cost over a raw pointer is minimal, and it adds (enforced) documentation that this is the "owning" pointer to this resource.
If you must have a resource whose lifetime is the union of the lifetime of a bunch of other objects, all of whom have unrelated lifetimes, shared_ptr can be considered. If your situation is so complex that a loop could possibly be formed, then naive shared_ptr use is no longer a practical option.
shared_ptr and weak_ptr can also be used as a distributed lifetime notification system, where a central location stores a (mostly unique) shared_ptr, and clients store weak_ptrs. Local (non-stored) shared_ptrs are created from the weak_ptrs in order to check that the target resource still exists, then the resource is manipulated, then the local shared_ptr is discarded. The goal here is to make (in a non-language enforced way) a unique_ptr with weak shares, so reasoning about lifetime is only marginally harder than the unique_ptr case.
shared_ptr basically never "solves" the lifetime problem without you proving that it will solve your lifetime problems. It can make some parts of that proof marginally easier.

Usage of Smart Pointers as a Programming Standard?

More and more I hear, that I should use smart pointers instead of naked pointers, despite I have effective memory leak system implemented.
What is the correct programming approach on using smart pointers please? Should they really be used, even if I check memory leaks on allocated memory blocks? Is it still up to me? If I do not use them, can this be considered as programming weakness?
If the smart pointers(ex: std::auto_ptr) are strongly recommended, should I use them instead of every naked pointer?
You should use RAII to handle all resource allocations.
Smart pointers are just one common special case of that rule.
And smart pointers are more than just shared_ptr. There are different smart pointers with different ownership semantics. Use the one that suits your needs. (The main ones are scoped_ptr, shared_ptr, weak_ptr and auto_ptr/unique_ptr (prefer the latter where available). Depending on your compiler, they may be available in the standard library, as part of TR1, or not at all, in which case you can get them through the Boost libraries.
And yes, you should absolutely use these. It costs you nothing (if done correctly, you lose zero performance), and it gains you a lot (memory and other resources are automatically freed, and you don't have to remember to handle it manually, and your code using the resource gets shorter and more concise)
Note that not every pointer usage represents some kind of resource ownership, and so not all raw pointer usage is wrong. If you simply need to point to an object owned by someone else, a raw pointer is perfectly suitable. But if you own the object, then you should take proper ownership of it, either by giving the class itself RAII semantics, or by wrapping it in a smart pointer.
You can't just blindly substitute std::auto_ptr for every raw pointer. In particular, auto_ptr transfers ownership on assignment, which is great for some purposes but definitely not for others.
There is a real reason there are several varieties of smart pointers (e.g., shared_ptr, weak_ptr, auto_ptr/unique_ptr, etc.) Each fulfills a different purpose. One major weakness of a "raw" pointer is that it has so many different uses (and has that versatility largely because it does little or nothing to assist in any one purpose). Smart pointers tend to be more specialized, which means they can be more intelligent about doing one thing well, but also means you have to pick the right one for the job or it'll end up dong the wrong things entirely.
Smart pointers allows to define automatically the life-time of objects it refers to. That's the main thing to understand.
So, no, you shouldn't use smart pointers everywhere, only when you want to automate life-time of your objects instead of having, for example, an object managing those objects inside from birth to death. It's like any tool : it solves specific kind of problems, not all problems.
For each object, you should think about the life cycle it will go through, then choose one of the simplest correct and efficient solution. Sometimes it will be shared_ptr because you want the object to be used by several components and to be automatically destroyed once not used anymore. Sometimes you need the object only in the current scope/parent-object, so scoped_ptr might be more appropriate. Sometimes you need only one owner of the instance, so unique_ptr is appropriate. Maybe you'll find cases where you know an algorithm that might define/automate the lifetime of an object, so you'll write your own smart pointer for it.
For example of opposite case, using pools forbids you to use smart_ptr. Naked pointers might be a more welcome simple and efficient solution in this particular (but common in embedded software) case.
See this answer (from me) for more explainations : https://softwareengineering.stackexchange.com/questions/57581/in-c-is-it-a-reflection-of-poor-software-design-if-objects-are-deleted-manuall/57611#57611
Should they really be used, even if I check memory leaks on allocated memory blocks?
YES
The whole purpose of smart pointers is, it help you implement RAII(SBRM), which basically lets the resource itself take the responsibility of its deallocation and the resource doesn't have to rely on you explicitly remembering to deallocate it.
If I do not use them, can this be considered as programming weakness?
NO,
It is not a weakness but a inconvenience or unnecessary hassle to explicitly manage the resources by yourself if you are not using Smart pointers(RAII). The purpose of smart pointers to implement RAII is to provide efficient and hassle free way of handling resources and you would just not be making use of it if you are not using it. It is highly recommended to use it purely for the numerous advantages it provides.
If the smart pointers(ex: std::auto_ptr)are strongly recommended, should I use them instead of every naked pointer?
YES
You should use smart pointers wherever possible because simply there is no drawback of using them and just numerous advantages to use them.
Don't use auto_ptr though because it is already deprecated!! There are various other smart pointers available that you can use depending on the requirement. You can refer the link above to know more about them.
It's a tricky question, and the fact that there is currently a mode to
use smart pointers everywhere doesn't make things any easier. Smart
pointers can help in certain situations, but you certainly can't just
use them everywhere, without thinking. There are many different types
of smart pointers, and you have to think about which one is appropriate
in every case; and even then, most of your pointers (at least in typical
applications in the domains I've worked in) should be raw pointers.
Regardless of the approach, several points are worth mentionning:
Don't use dynamic allocation unless you have to. In many
applications, the only things that need to be allocated dynamically
are objects with specific lifetimes, determined by the application
logic. Don't use dynamic allocation for objects with value semantics.
With regards to entity object, those which model something in the
application domain: these should be created and destructed according
to the program logic. Irregardless of whether there are pointers to
them or not. If their destruction causes a problem, then you have an
error in your program logic somewhere (not handling an event correctly,
etc.), and using smart pointers won't change anything.
A typical example of an entity object might be client connection in a
server, is created when the client connects, and destructed when the
client disconnects. In many such cases, the most appropriate management
will be a delete this, since it is the connection which will receive
the disconnection event. (Objects which hold pointers to such an object
will have to register with it, in order to be informed of its
destruction. But such pointers are purely for navigation, and shouldn't
be smart pointers.)
What you'll usually find when people try to use smart pointers
everywhere is that memory leaks; typical reference counters don't
handle cycles, and of course, typical applications are full of cycles: a
Connection will point to the Client which is connected to it, and
the Client will contain a list of Connection where it is connected.
And if the smart pointer is boost::shared_ptr, there's also a definite
risk of dangling pointers: it's far to easy to create two
boost::shared_ptr to the same address (which results in two counters
for the references).
If the smart pointers(ex: std::auto_ptr) are strongly recommended, should I use them instead of every naked pointer?
In my opinion, yes, you should it for every pointer that you own.
Here are my ideas on resource management in C++ (feel free to disagree):
Good resource management requires thinking in terms of ownership.
Resources should be managed managed by objects (RAII).
Usually single ownership is preferred over shared ownership.
Ideally the creator is also the owner of the object. (However, there are situations where ownership transfer is in order.)
This leads to the following practices:
Make boost::scoped_ptr the default choice for local and member variables. Do keep in mind that using scoped_ptr for member variables will make your class non-copyable. If you don't want this see next point.
Use boost::shared_ptr for containers or to enable shared ownership:
// Container of MyClass* pointers:
typedef boost::shared_ptr<MyClass> MyClassPtr;
std::vector<MyClassPtr> vec;
The std::auto_ptr (C++03) can be used for ownership transfer. For example as the return value of factory or clone methods:
// Factory method returns auto_ptr
std::auto_ptr<Button> button = Button::Create(...);
// Clone method returns auto_ptr
std::auto_ptr<MyClass> copy = obj->clone();
// Use release() to transfer the ownership to a scoped_ptr or shared_ptr
boost::scoped_ptr<MyClass> copy(obj->clone().release());
If you need to store a pointer that you don't own then you can use a raw pointer:
this->parent = inParentObject;
In certain situations a boost::weak_pointer is required. See the documentation for more information.
In general you should prefer smart pointers, but there are a couple of exceptions.
If you need to recast a pointer, for example to provide a const version, that becomes nearly impossible with smart pointers.
Smart pointers are used to control object lifetime. Often when you are passing a pointer to a function, the function will not affect the lifetime; the function does not try to delete the object, and it does not store a copy of the pointer. The calling code cannot delete the object until the function returns. In that case a dumb pointer is perfectly acceptable.
Yes. Assuming you have C++0x available to you, use unique_ptr or shared_ptr (as appropriate) to wrap all the raw pointers you new up. With the help of make_shared, shared_ptr is highly performant. If you don't need reference counting then unique_ptr will get you better perf. Both of them behave properly in collections and other circumstances where auto_ptr was a dumb pointer.
Using smart pointers (shared_ptr or otherwise) EVERYWHERE is a bad idea. It's good to use shared_ptr to manage the lifetime of objects/resources but it's not a good idea to pass them as parameters to functions etc. That increases the likelihood of circular references and other extremely hard to track bugs (Personal experience: Try figuring out who should not be holding onto a resource in 2 millions lines of code if every function invocation changes the reference count - you will end up thinking the guys who do this kind of thing are m***ns). Better to pass a raw pointer or a reference.
The situation is even worse when combined with lazy instantiation.
I would suggest that developers should know the lifecycle of the objects they write and use shared_ptr to control that (RAII) but not extend shared_ptr use beyond that.

Getting started with smart pointers in C++

I have a C++ application which makes extensively use of pointers to maintain quite complex data structures. The application performs mathematical simulations on huge data sets (which could take several GB of memory), and is compiled using Microsoft's Visual Studio 2010.
I am now reworking an important part of the application. To reduce errors (dangling pointers, memory leaks, ...) I would want to start using smart pointers. Sacrificing memory or performance is acceptible as long as it is limited.
In practice most of the classes are maintained in big pools (one pool per class) and although the classes can refer to each other, you could consider the pool as owner of all the instances of that class. However, if the pool decides to delete an instance, I don't want any of the other classes that still refers to the deleted instance to have a dangling pointer.
In another part I keep a collection of pointers to instances that are delivered by other modules in the application. In practice the other modules maintain ownership of the passed instance, but in some cases, modules don't want to take care of the ownership and just want to pass the instance to the collection, telling it "it's yours now, manage it".
What is the best way to start introducing smart pointers? Just replacing pointers [at random] with smart pointers doesn't seem a correct way, and probably doesn't deliver all the (or any of the) advantages of smart pointers. But what is a better method?
Which types of smart pointers should I further investigate? I sometimes use std::auto_ptr for the deallocation of locally allocated memory, but this seems to be deprected in C++0x. Is std::unique_ptr a better alternative? Or should I go straight to shared pointers or other types of smart pointers?
The question Replacing existing raw pointers with smart pointers seems similar but instead of asking how easy it is, I am asking what the best approach would be, and which kind of smart pointers are suited best.
Thanks in advance for your ideas and suggestions.
I recommend using unique_ptr when possible (this may require some program analysis) and shared_ptr when this is impossible. When in doubt, use a shared_ptr to maximize safety: when handing off control to a container, the reference count will simply go to two and then back to one and the container will eventually delete the associated object automatically. When performance becomes an issue, consider using boost::intrusive_ptr.
Here are the 3 varieties found in the new C++11 standard (unique_ptr replaces auto_ptr)
http://www.stroustrup.com/C++11FAQ.html#std-unique_ptr
http://www.stroustrup.com/C++11FAQ.html#std-shared_ptr
http://www.stroustrup.com/C++11FAQ.html#std-weak_ptr
You can read the text for each pointer and there is an explanation of when to use which in there. For local memory management unique_ptr is the choice. It is non-copyable but movable so as you move it around the receiver takes ownership of it.
Shared_ptr is used if you want to share an object instance around with no one really owning the object and to make sure it doesn't get deleted while someone still has a reference to it. Once the last user of an object destroys the shared_ptr container, the contained object will be deleted.
weak_ptr is used in conjunction with shared_ptr. It enables one to "lock" to see if the reference shared_ptr object still exists before trying to access the internal object.

smart pointers + "this" considered harmful?

In a C++ project that uses smart pointers, such as boost::shared_ptr, what is a good design philosophy regarding use of "this"?
Consider that:
It's dangerous to store the raw pointer contained in any smart pointer for later use. You've given up control of object deletion and trust the smart pointer to do it at the right time.
Non-static class members intrinsically use a this pointer. It's a raw pointer and that can't be changed.
If I ever store this in another variable or pass it to another function which could potentially store it for later or bind it in a callback, I'm creating bugs that are introduced when anyone decides to make a shared pointer to my class.
Given that, when is it ever appropriate for me to explicitly use a this pointer? Are there design paradigms that can prevent bugs related to this?
Wrong question
In a C++ project that uses smart pointers
The issue has nothing to do with smart pointers actually. It is only about ownership.
Smart pointers are just tools
They change nothing WRT the concept of ownership, esp. the need to have well-defined ownership in your program, the fact that ownership can be voluntarily transferred, but cannot be taken by a client.
You must understand that smart pointers (also locks and other RAII objects) represent a value and a relationship WRT this value at the same time. A shared_ptr is a reference to an object and establishes a relationship: the object must not be destroyed before this shared_ptr, and when this shared_ptr is destroyed, if it is the last one aliasing this object, the object must be destroyed immediately. (unique_ptr can be viewed as a special case of shared_ptr where there is zero aliasing by definition, so the unique_ptr is always the last one aliasing an object.)
Why you should use smart pointers
It is recommended to use smart pointers because they express a lot with only variables and functions declarations.
Smart pointers can only express a well-defined design, they don't take away the need to define ownership. In contrast, garbage collection takes away the need to define who is responsible for memory deallocation. (But do not take away the need to define who is responsible for other resources clean-up.)
Even in non-purely functional garbage collected languages, you need to make ownership clear: you don't want to overwrite the value of an object if other components still need the old value. This is notably true in Java, where the concept of ownership of mutable data structure is extremely important in threaded programs.
What about raw pointers?
The use of a raw pointer does not mean there is no ownership. It's just not described by a variable declaration. It can be described in comments, in your design documents, etc.
That's why many C++ programmers consider that using raw pointers instead of the adequate smart pointer is inferior: because it's less expressive (I have avoided the terms "good" and "bad" on purpose). I believe the Linux kernel would be more readable with a few C++ objects to express relationships.
You can implement a specific design with or without smart pointers. The implementation that uses smart pointer appropriately will be considered superior by many C++ programmers.
Your real question
In a C++ project, what is a good design philosophy regarding use of "this"?
That's awfully vague.
It's dangerous to store the raw pointer for later use.
Why do you need to a pointer for later use?
You've given up control of object deletion and trust the responsible component to do it at the right time.
Indeed, some component is responsible for the lifetime of the variable. You cannot take the responsibility: it has to be transferred.
If I ever store this in another variable or pass it to another function which could potentially store it for later or bind it in a callback, I'm creating bugs that are introduced when anyone decides to use my class.
Obviously, since the caller is not informed that the function will hide a pointer and use it later without the control of the caller, you are creating bugs.
The solution is obviously to either:
transfer responsibility to handle the lifetime of the object to the function
ensure that the pointer is only saved and used under the control of the caller
Only in the first case, you might end up with a smart pointer in the class implementation.
The source of your problem
I think that your problem is that you are trying hard to complicate matters using smart pointers. Smart pointers are tools to make things easier, not harder. If smart pointers complicate your specification, then rethink your spec in term of simpler things.
Don't try to introduce smart pointers as a solution before you have a problem.
Only introduce smart pointers to solve a specific well-defined problem. Because you don't describe a specific well-defined problem, it is not possible to discuss a specific solution (involving smart pointers or not).
While i don't have a general answer or some idiom, there is boost::enable_shared_from_this . It allows you to get a shared_ptr managing an object that is already managed by shared_ptr. Since in a member function you have no reference to those managing shared_ptr's, enable_shared_ptr does allow you to get a shared_ptr instance and pass that when you need to pass the this pointer.
But this won't solve the issue of passing this from within the constructor, since at that time, no shared_ptr is managing your object yet.
One example of correct use is return *this; in functions like operator++() and operator<<().
When you are using a smart pointer class, you are right that is dangerous to directly expose "this". There are some pointer classes related to boost::shared_ptr<T> that may be of use:
boost::enable_shared_from_this<T>
Provides the ability to have an object return a shared pointer to itself that uses the same reference counting data as an existing shared pointer to the object
boost::weak_ptr<T>
Works hand-in-hand with shared pointers, but do not hold a reference to the object. If all the shared pointers go away and the object is released, a weak pointer will be able to tell that the object no longer exists and will return you NULL instead of a pointer to invalid memory. You can use weak pointers to get shared pointers to a valid reference-counted object.
Neither of these is foolproof, of course, but they'll at least make your code more stable and secure while providing appropriate access and reference counting for your objects.
If you need to use this, just use it explicitly. Smart pointers wrap only pointers of the objects they own - either exclusivelly (unique_ptr) or in a shared manner (shared_ptr).
I personally like to use the this pointer when accessing member variables of the class. For example:
void foo::bar ()
{
this->some_var += 7;
}
It's just a harmless question of style. Some people like it, somepeople don't.
But using the this pointer for any other thing is likely to cause problems. If you really need to do fancy things with it, you should really reconsider your design. I once saw some code that, in the constructor of a class, it assigned the this pointer to another pointer stored somewhere else! That's just crazy, and I can't ever think of a reason to do that. The whole code was a huge mess, by the way.
Can you tell us what exactly do you want to do with the pointer?
Another option is using intrusive smart pointers, and taking care of reference counting within the object itself, not the pointers. This requires a bit more work, but is actually more efficient and easy to control.
Another reason to pass around this is if you want to keep a central registry of all of the objects. In the constructor, an object calls a static method of the registry with this. Its useful for various publish/subscribe mechanisms, or when you don't want the registry to need knowledge of what objects/classes are in the system.