Professional C__ - Marc Gregoire [375]
Some languages provide garbage collection so that programmers are not responsible for freeing any memory. In these languages, all pointers can be thought of as smart pointers because you don’t need to remember to free any of the memory to which they point. Although some languages, such as Java, provide garbage collection as a matter of course, it is very difficult to write a garbage collector for C++. Thus, smart pointers are simply a technique to make up for the fact that C++ exposes memory management without garbage collection.
C++ provides several language features that make smart pointers attractive. First, you can write a type-safe smart pointer class for any pointer type using templates. Second, you can provide an interface to the smart pointer objects using operator overloading that allows code to use the smart pointer objects as if they were dumb pointers. Specifically, you can overload the * and -> operators such that the client code can dereference a smart pointer object the same way it dereferences a normal pointer.
The Old Deprecated auto_ptr
The old, pre-C++11 standard template library included a basic implementation of a smart pointer, called auto_ptr. Unfortunately, auto_ptr has some serious shortcomings. One of these shortcomings is that it does not work correctly when used inside STL containers like vectors. C++11 has officially deprecated auto_ptr and replaced it with shared_ptr and unique_ptr, discussed in the next section. auto_ptr is mentioned here to make sure you know about it and to make sure you never use it.
Do not use the old auto_ptr smart pointer anymore. Instead use the new C++11 shared_ptr or unique_ptr!
The New C++11 Smart Pointers
C++11 introduces two new smart pointer classes: shared_ptr and unique_ptr. The difference between the two is that shared_ptr is a reference counted smart pointer, while unique_ptr is not reference counted. This means that you can have several shared_ptr instances pointing to the same dynamically allocated memory and the memory will only be deallocated when the last shared_ptr goes out of scope. For this reason, shared_ptr is safer/easier to use compared to unique_ptr. Most of the remainder of this section focuses on the shared_ptr template.
As a rule of thumb, always store dynamically allocated objects in stack-based instances of shared_ptr. For example, consider the following function that blatantly leaks memory by allocating a Simple object on the heap and neglecting to release it:
void leaky()
{
Simple* mySimplePtr = new Simple(); // BUG! Memory is never released!
mySimplePtr->go();
}
Using the shared_ptr template, the object is still not explicitly deleted; but when the shared_ptr instance goes out of scope (at the end of the function) it automatically deallocates the Simple object in its destructor:
void notLeaky()
{
shared_ptr mySimpleSmartPtr->go(); } You need to include the Sometimes you might think that your code is properly deallocating dynamically allocated memory. Unfortunately, it most likely is not correct in all situations. Take the following function: void couldBeLeaky() { Simple* mySimplePtr = new Simple(); mySimplePtr->go(); delete mySimplePtr; } The above function dynamically allocates a Simple object, uses the object, and then properly calls