Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type erasure in C++: how boost::shared_ptr and boost::function work?

Tags:

Type erasure - is that how you call it?

How boost::shared_ptr stores its deleter and how boost::function stores its function object?

Is there any tutorial that teaches the trick?

What is the run-time cost of using type-erased function objects?

like image 599
pic11 Avatar asked Jun 12 '11 21:06

pic11


People also ask

What is boost :: shared_ptr?

shared_ptr is now part of the C++11 Standard, as std::shared_ptr . Starting with Boost release 1.53, shared_ptr can be used to hold a pointer to a dynamically allocated array. This is accomplished by using an array type ( T[] or T[N] ) as the template parameter.

What does shared_ptr get () do?

std::shared_ptr::getReturns the stored pointer. The stored pointer points to the object the shared_ptr object dereferences to, which is generally the same as its owned pointer.

Where is std :: shared_ptr defined?

If your C++ implementation supports C++11 (or at least the C++11 shared_ptr ), then std::shared_ptr will be defined in <memory> . If your C++ implementation supports the C++ TR1 library extensions, then std::tr1::shared_ptr will likely be in <memory> (Microsoft Visual C++) or <tr1/memory> (g++'s libstdc++).

What is the best way to delete an object managed by shared_ptr?

If shared_ptr::unique returns true, then calling shared_ptr::reset will delete the managed object. However, if shared_ptr::unique returns false, it means there are more than one shared_ptr s sharing ownership of that object.


1 Answers

The idea is simple, you define a base class that has an interface with the functionality you need, and then inherit from it. Since the type erased class uses only that interface, the actual type underneath is forgotten and erased. Alternatively, if the only needed interface can be expressed as free functions you can store pointers to the free functions.

namespace detail {    struct deleter_base {       virtual ~deleter_base() {}       virtual void operator()( void* ) = 0;    };    template <typename T>    struct deleter : deleter_base {       virtual void operator()( void* p ) {          delete static_cast<T*>(p);       }    }; } template <typename T> class simple_ptr {    T* ptr;    detail::deleter_base* deleter; public:    template <typename U>    simple_ptr( U* p ) {       ptr = p;       deleter = new detail::deleter<U>();    }    ~simple_ptr() {       (*deleter)( ptr );       delete deleter;    } }; 

This is a really simplified smart pointer, but the idea is there. In the particular case of shared_ptr, the deleter is stored as part of the reference count object, that is held by pointer.

like image 90
David Rodríguez - dribeas Avatar answered Mar 25 '23 12:03

David Rodríguez - dribeas