C++ Programming/Operators/Pointers/Smart Pointers
This page may need to be updated to reflect current knowledge. Since C++11 auto_ptr is deprecated and should no longer be used. Instead of auto_ptr you should use the new smart pointers: unique_ptr, weak_ptr and shared_ptr. unique_ptr should now be preferred as replacement for auto_ptr. You can help update it, discuss progress, or request assistance. |
Smart Pointers
editUsing raw pointers to store allocated data and then cleaning them up in the destructor can generally be considered a very bad idea since it is error-prone. Even temporarily storing allocated data in a raw pointer and then deleting it when done with it should be avoided for this reason. For example, if your code throws an exception, it can be cumbersome to properly catch the exception and delete all allocated objects.
Smart pointers can alleviate this headache by using the compiler and language semantics to ensure the pointer content is automatically released when the pointer itself goes out of scope.
#include <memory>
class A
{
public:
virtual ~A() {}
virtual char val() = 0;
};
class B : public A
{
public:
virtual char val() { return 'B'; }
};
A* get_a_new_b()
{
return new B();
}
bool some_func()
{
bool rval = true;
std::auto_ptr<A> a( get_a_new_b() );
try {
std::cout << a->val();
} catch(...) {
if( !a.get() ) {
throw "Memory allocation failure!";
}
rval = false;
}
return rval;
}
Semantics
editThe auto_ptr has semantics of strict ownership, meaning that the auto_ptr instance is the sole entity responsible for the object's lifetime. If an auto_ptr is copied, the source loses the reference. For example:
#include <iostream>
#include <memory>
using namespace std;
int main(int argc, char **arv)
{
int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;
y = x;
cout << x.get() << endl;
cout << y.get() << endl;
}
This code will print a NULL address for the first auto_ptr object and some non-NULL address for the second, showing that the source object lost the reference during the assignment (=). The raw pointer i
in the example should not be deleted, as it will be deleted by the auto_ptr that owns the reference. In fact, new int
could be passed directly into x, eliminating the need for i
.
Notice that the object pointed by an auto_ptr is destructed using operator delete
; this means that you should only use auto_ptr for pointers obtained with operator new
. This excludes pointers returned by malloc(), calloc() or realloc()
and operator new[]
.