Pages

boost::lexical_cast

As an 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, and these are a few notes that I'm jotting down in the meanwhile.

Converting data from strings to numeric types is a boring and error prone task, luckly we can use lexical_cast, as showed in this example:

#include <iostream>
#include <string>
#include "boost/lexical_cast.hpp"

using std::string;
using std::cout;
using std::endl;
using boost::lexical_cast;
using boost::bad_lexical_cast;

void lexical()
{
// string to int
string s("42");
int i = lexical_cast<int>(s);
cout << "fortytwo as string " << s << " and as int " << i << endl;

// float to string
float f = 3.14151;
s = lexical_cast<std::string>(f);
cout << "PI as float " << f << " and as string " << s << endl;

// literal to double
double d = lexical_cast<double>("2.52");
cout << "A double from a string " << d << endl;

// Failed conversion
s = "Not an int";
try
{
i = lexical_cast<int>(s);
}
catch(bad_lexical_cast& blc)
{
cout << "Exception " << blc.what() << endl;
}
}

It is easy to think about a template function that would convert to a string its input:

#include <iostream>
#include <string>
#include "boost/lexical_cast.hpp"

using std::string;
using std::cout;
using std::endl;
using boost::lexical_cast;
using boost::bad_lexical_cast;

namespace
{
template <typename T>
string toString(const T& arg)
{
try {
return lexical_cast<string>(arg);
}
catch(boost::bad_lexical_cast& e) {
return "";
}
}
}

void lexical2()
{
string s = toString(42);
cout << "int to string " << s << endl;

s = toString(3.14151);
cout << "float to string " << s << endl;
}

Go to the full post

boost::weak_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, and these are a few notes that I'm jotting down in the meanwhile.

Sometimes it is useful to have a way to keep an eye on a resource without actually claiming for its ownership. That is actually the point of weak_ptr. It is a duty of the related shared_ptr to set to null the pointer in weak_ptr when it is ready to release it.

What we have to do, is checking the weak_ptr validity, through its method expired(). Then, if we actually want to use the resource, we could create a shared_ptr from the weak_ptr.

Here is a short example:

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

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

namespace
{
class A
{
public:
void hello() { cout << "Hello from A" << endl; }
};
}

void weakPtr()
{
weak_ptr<A> w;
if(w.expired())
cout << "No associated shared_ptr" << endl;

{
shared_ptr<A> p(new A());
p->hello();

w = p;
// w->hello(); // we can't do that!

cout << "A weak_ptr do not increase the reference count: " << p.use_count() << endl;

// Create a shared_ptr from the weak_ptr
shared_ptr<A> p2(w);
cout << "Now the reference count is " << p.use_count() << endl;
}


if(w.expired())
cout << "The shared_ptr is expired" << endl;

cout << "If we create a new shared_ptr using lock() ..." << endl;
shared_ptr<A> p3 = w.lock();

if(!p3)
cout << "... we should check it is valid before using it" << endl;

try
{
cout << "If we create a new shared_ptr passing the weak_ptr to its ctor ..." << endl;
shared_ptr<A> p3(w);
}
catch(const bad_weak_ptr& bwp)
{
cout << "... it could throw a " << bwp.what() << " exception" << endl;
}
}

Go to the full post

boost::shared_ptr and this


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, and these are a few notes that I'm jotting down in the meanwhile.

Let's say we have a class A, and we want to call from one of its methods a free function that accept as input parameter a shared_ptr to A.

There is a relatively simple way to get it. We could let our class A derive from enable_shared_from_this<A> and use shared_from_this() to get the shared_ptr.

Here is a short example that shows this feature:

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

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

namespace
{
class A;
void doStuff(shared_ptr<A> p);

class A : public enable_shared_from_this<A>
{
public:
void callDoStuff()
{
cout << "in A::callDoStuff()" << endl;
doStuff(shared_from_this());
}

void cheers() { cout << "Cheers from A" << endl; }
};

void doStuff(shared_ptr<A> p)
{
cout << "Doing stuff in doStuff()" << endl;
p->cheers();
}
}

void sharedThis()
{
shared_ptr<A> p(new A());
p->callDoStuff();
}

Go to the full post

Custom deleter for 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, and these are a few notes that I'm jotting down in the meanwhile.

The shared_ptr custom deleter is helpful for handling resources that need something more that calling a simple delete on the pointer.

As example, here we see how to manage a stdio FILE pointer via shared_ptr.

We define a functor, FileCloser, to perform the cleanup operation. Actually, if we were not interested in other than calling fclose(), we could avoid using the functor, and just passing the function to the shared_ptr constructor as custom deleter. Here we want some simple logging, to show how and when the deleter is called, so we do use the functor.

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

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

namespace
{
class FileCloser
{
public:
void operator()(FILE* file)
{
cout << "FileCloser in action!" << endl;
if(file != 0)
fclose(file);
}
};
}

void filePtr() {
cout << "shared_ptr example with a custom deallocator" << endl;

{
FILE* f = fopen("smart04.cpp","r");
if(f == 0)
{
cout << "Unable to open file" << endl;
return;
}

shared_ptr<FILE> sharedFile(f, FileCloser());
fseek(sharedFile.get(), 42, SEEK_SET);
}
cout << "FILE closed by the shared_ptr custom deleter" << endl;
}

We could also use the custom deleter to implement a better security on the type.

Declaring the destructor as protected (or private) and use an inner functor as custom deleter will do the trick. In this case we declare the functor as private inner class, so, in order to call the shared_ptr constructor passing the functor as custom deleter, we have to define a public function of the class, otherwise there would be no access right to the functor.


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

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

namespace
{
class A
{
class ADeleter
{
public:
void operator()(A* p)
{
cout << "ADeleter in action" << endl;
delete p;
}
};

public:
virtual void sing()
{
cout << "Lalalalalalalalalalala" << endl;
}

static boost::shared_ptr<A> createA()
{
shared_ptr<A> p(new A(), A::ADeleter());
return p;
}

protected:
virtual ~A() {};
};
}

void safePtr()
{
shared_ptr<A> p = A::createA();
p->sing();

// A a; // do not compile: dtor protected
A* a = p.get();
a->sing();
// delete a; // do not compile: protected
}

Go to the full post

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));
}

Go to the full post

boost::scoped_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.

The smart pointer scoped_ptr is close in its meaning to const auto_ptr, the major difference being is that the first has a reset() method that could be used to deleting or replacing the actual pointee, when required.

A scoped_ptr can't be copied, so using it makes clear that we want to use the pointee just in the current scope, and we want it to be deleted when we leave it.

Here is a little nonsensical example:

#include "boost/scoped_ptr.hpp"
#include <string>
#include <iostream>

using std::cout;
using std::endl;
using std::string;
using boost::scoped_ptr;

void scoped() {
// a string is created on the heap and used to initialize the smart pointer
scoped_ptr<string> p(new string("Use scoped_ptr often."));

// it is available an operator unspecified_bool_type()
if(p)
cout << *p << endl;

// smart pointer means we have access to the pointee methods
size_t i=p->size();
cout << "String size is " << i << endl;

*p = "Acts just like a pointer";

cout << "Now string is: " << *p << endl;

// the string on the heap is deleted automatically
}

Go to the full post

Restart

Dramatic change in the blog. I restart from scratch, in English this time.

Be patient if I make mistakes, I am Italian, after all ;-)

Go to the full post