C++ Boost Smart Pointers, these are template classes that implements a garbage collection system in C++, isnt that pretty neat? Now this means that you dont need to bother remembering to free all those pointers that you created because these templates will be the one making sure they are freed. You can download Boost library from their website download page.
These are the different templates for boost smart pointers:
- scoped_ptr
The same with std::auto_ptr that is noncopyable - scoped_array
The same with std::auto_ptr that is noncopyable but for arrays, pointer created using new[] - shared_ptr
Pointers can be shared with this. - shared_array
Same as shared_ptr but for arrays - intrusive_ptr
these templates will not release the pointers but will call functions when its constructor and destructor will be called
scoped_ptr and scoped_array
As what their name suggests these templates are used for encapsulating pointers that will only live for the current scope. This is also much like std::auto_ptr in which they are also not copyable. Example usage
void foo( void ) { boost::scoped_ptr< int > i1(new int); *i1 = 5; if ( *i1 == 5 ) { boost::scoped_ptr< int > i2( new int ); *i2 = 5; //i2 will only live up to here. //scoped pointer will automatically release the memory for i2 } //i1 will live up to here //scoped pointer will automatically release the memory for i1 }
shared_ptr and shared_array
These templates has a reference counter for the pointer they hold. Every copy of this will add to the reference counter and every call on the shared_ptr destructor will subtract on the reference counter. If this reference counter reach 0 the pointer will be automatically freed. Example usage
#include <iostream> #include <boost/shared_ptr.hpp> class foo { public: foo() {} boost::shared_ptr< int > num; }; int main( int argc, char* argv[] ) { foo f; if ( argc > 1 ) { boost::shared_ptr< int > num( new int ); std::cout << "current count: " << num.use_count() << std::endl; *num = 4; f.num = num; //num reference count will increase to 2 std::cout << "current count: " << num.use_count() << std::endl; } else { std::cout << "Expected 1 argument"; } std::cout << "current count: " << f.num.use_count() << std::endl; //reference count will be 1 return 0; }
weak_ptr
weak_ptr these templates will point to the pointer pointed by shared_ptr but doesnt own it. These means that what it is pointing might be already freed by shared_ptr. Example usage:
#include <iostream> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> class foo { public: foo() num( new int ) {} boost::weak_ptr get_num( void ) const { return num; } private: boost::shared_ptr< int > num; } int main( int argc, char* argv[] ) { boost::weak_ptr< int > weak; { foo f; weak = f.get_num(); if ( !weak.expired() ) { std::cout << *weak.lock() << std::endl; } //since f will be destroyed here and so does its member num //weak will reset and its expired() method will return true } std::cout << weak.expired() << std::endl; return 0; }
Note: make sure you first call expired() to check if the pointer is still valid. Then call lock() this will return a shared_ptr, so that it will not be freed while you are accessing it.
intrusive_ptr
The application must have a function called intrusive_ptr_add_ref and intrusive_ptr_release with template arguments. These functions will be called by intrusive_ptr on its creation and destruction respectively. Since intrusive_ptr doenst release the pointer, intrusive_ptr_release shall be tasked of releasing the pointer once the counter reaches 0.
Example usage:
#include <iostream> #include <boost/intrusive_ptr.hpp> template <class T> void intrusive_ptr_add_ref( T *t ) { t->addCount(); } template <class T> void intrusive_ptr_release( T *t ) { t->subCount(); if ( t->count() == 0 ) { delete t; } } class foo { long refCount; public: foo() : refCount(0) {} void addCount(void) { refCount++; } void subCount(void) { refCount--; } long count(void) const { return refCount; } }; int main( int argc, char* argv[] ){ boost::intrusive_ptr<foo> a(new foo); //intrusive_ptr_add_ref will be called here return 0; //intrusive_ptr_release will be called here, that will cause to release foo }
With these 5 template classes for memory management you can now be a pointer maniac creating pointer every where without worrie
Leave a Reply