boost::shared_ptr

As a good introduction to some of the most interesting boost libraries you can read "Beyond the C++ Standard Library: An Introduction to Boost", by Björn Karlsson, an Addison Wesley Professional book. That's what I'm actually doing now to refresh the subject. And these are a few notes that I'm jotting down in the meanwhile.

If we need a reference counted smart pointer we should consider using shared_ptr. It is useful in case there is no explicit owner for the pointee, so we should delete it only when no one is still actually owning it.

It also works fine with the STL containers. Besides, using the chance of passing it a custom deleter, the shared_ptr is a good choice to manage resources that need a special cleanup.

Here is a first simple example:

#include <iostream>
#include "boost/shared_ptr.hpp"

using std::cout;
using std::endl;
using boost::shared_ptr;

namespace
{
class A
{
private:
shared_ptr<int> no_;
public:
A(shared_ptr<int> no) : no_(no) {}

void setValue(int i) { *no_=i; }
};

class B
{
private:
shared_ptr<int> no_;
public:
B(shared_ptr<int> no) : no_(no) {}

int getValue() const { return *no_; }
};
}

void shared()
{
shared_ptr<int> temp(new int(14));
A a(temp);
B b(temp);

cout << "B value is initialized to " << b.getValue() << endl;

a.setValue(28);
cout << "B value has been indirectly changed to " << b.getValue() << endl;
}

A typical usage of shared_ptr is in conjunction with STL containers. Using values lead to the slicing problem, using pointers lead to an high degree of complexity. With shared_ptr we solve both issues.

No slicing, and a clean design, as we can see in this example:

#include <vector>
#include <iostream>
#include <functional>

#include "boost/shared_ptr.hpp"
#include "boost/bind.hpp"

using std::cout;
using std::endl;
using std::vector;
using std::for_each;

using boost::shared_ptr;
using boost::bind;

namespace
{
class A
{
public:
virtual void sing()=0;
protected:
virtual ~A() {};
};

class B : public A
{
public:
virtual void sing() { cout << "Do re mi fa so la" << endl; }
};

shared_ptr<A> createA()
{
shared_ptr<A> p(new B());
return p;
}
}

void vectorPtr()
{
vector<shared_ptr<A> > vec;
for(int i = 0; i < 10; ++i)
vec.push_back(createA());

cout << "The choir is gathered: " << endl;
for_each(vec.begin(), vec.end(), bind(&A::sing, _1));
}

No comments:

Post a Comment