During various discussion on
comp.lang.c++.moderated I wanted to change
some of the boost smart pointers s.t. they
propagated constness which I thought was the
real thing to do. I was using eg. shared_ptr a
holder for my delegation pointer together with the
Pimlp idiom.
I came to realize that modifying the boost smart
pointers was a bad idea because it somehow gave
too many concerns to one class. Instead I could
build a special class to fit my needs wrt.
the Pimpl idiom (sounds pretty simple, right
:-)).
So I did. Know I would like to hear if others have
felt the need for such classses and if so what they did.
I will post the interface here and the
implementation if people would like it, but there are not really any
surprises
in the implementation. Here's the
interface:
/**
* Template for implementing referenced counted Pimpls with minimal
* effort. One should also use it in an interface delegating
* class with shallow copy semantics.
*
* The template preserves the semantics of the
* underlying reference counted pointer with respect
* to assignment and constructio/destruction.
* This means that copy-assignment,
* copy-constructor and destructor are default
* generated and rely on the correctness of
* the 'boost::shared_ptr'. These operators never throws.
* Moreover, it means that the class that only aggregates a single
* 'Shared_pimpl' doesn't need to define these operators and
* that holds as long only PODs are added to the class.
*
* The new features are
* that constness is propagated, that
* the interface is simpler and that the class can be cloned.
*
* @see http://www.boost.org/libs/smart_ptr/shared_ptr.htm
*/
template< typename T >
class Shared_pimpl
{
typedef typename boost::shared_ptr<T> ptr_type;
ptr_type ptr_;
public:
typedef typename ptr_type::bool_type bool_type;
public:
explicit Shared_pimpl( T* = 0 ); // @strong
Shared_pimpl( std::auto_ptr<T>& ); // @strong
T& operator*(); // @nothrow
const T& operator*() const; // @nothrow
T* operator->(); // @nothrow
const T* operator->() const; // @nothrow
std::auto_ptr<T> clone() const; // @strong
T* raw_clone() const; // @strong
void make_unique(); // @strong
operator bool_type() const // @nothrow
{
return ptr_.operator bool_type();
}
};
template< typename T >
void swap( Shared_pimpl<T>&, Shared_pimpl<T>& ); // @nothrow
/**
* Copy-on-write version of 'Shared_pimpl'. Every time the
* pointer is accessed, the pointed to object will be copied if
* more than one pointer points to it.
*/
template< typename T >
class Cow_pimpl
{
typedef typename boost::shared_ptr<T> ptr_type;
ptr_type ptr_;
public:
typedef typename ptr_type::bool_type bool_type;
public:
explicit Cow_pimpl( T* = 0 ); // @strong
Cow_pimpl( std::auto_ptr<T>& ); // @strong
T& operator*(); // @strong
const T& operator*() const; // @nothrow
T* operator->(); // @strong
const T* operator->() const; // @nothrow
std::auto_ptr<T> clone() const; // @strong
T* raw_clone() const; // @strong
operator bool_type() const // @nothrow
{
return ptr_.operator bool_type();
}
private:
void make_unique(); // @strong
};
template< typename T >
void swap( Cow_pimpl<T>&, Cow_pimpl<T>& ); // @nothrow
/**
* Template for implementing value type ( aka deep copied )
* Pimpls with minimal effort.
* One should also use it in an interface delegating
* class with deep copy semantics.
*
* The template offers deep copy
* semantics, that is, the copy-constructor and
* copy-assignment operator makes an strongly exception-safe clone of the
* object each time. A class that only aggregates a single 'Scoped_pimpl'
* need not define these operators. Moreover, one can rely on the compiler
* generated operators if one only adds PODs to the class.
*
* The new features are
* that constness is propagated and that
* deep copy semantics have been added.
*
* The correctness of the auto-generated destructor follows from
* the correctness of 'boost::scoped_ptr'. In particular, it can never
* throw.
*
* @see http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
*/
template< typename T >
class Scoped_pimpl
{
typedef boost::scoped_ptr<T> ptr_type;
ptr_type ptr_;
public:
typedef T* (ptr_type::*bool_type)() const;
public:
explicit Scoped_pimpl( T* = 0 ); // @nothrow
Scoped_pimpl( std::auto_ptr<T>& ); // @nothrow
Scoped_pimpl( const Scoped_pimpl& ); // @strong
Scoped_pimpl& operator=( const Scoped_pimpl& ); // @strong
T& operator*(); // @nothrow
const T& operator*() const; // @nothrow
T* operator->(); // @nothrow
const T* operator->() const; // @nothrow
std::auto_ptr<T> clone() const; // @strong
T* raw_clone() const; // @strong
operator bool_type() const // @nothrow
{
return ptr_.get() == 0 ? 0 : &ptr_type::get;
}
};
template< typename T >
void swap( Scoped_pimpl<T>&, Scoped_pimpl<T>& ); // @nothrow
Thorsten Ottosen, AAU
nesotto@cs.auc.dk---------------------------------------------------
C++:
my_map[key]++;
Java:
if ( !my_map.containsKey( key )
)
my_map.put( key, new Integer( 1 )
);
else
{
Integer count = ( Integer )my_map.get( key
) );
int icount = count.IntValue();
my_map.put( key, new Integer( ++icount ) );
}