|
Boost : |
From: Alex Burton (alexibu_at_[hidden])
Date: 2007-06-08 00:47:30
Hello Boost developers
<Class definition below>
I understand there would be a collision with boost::weak_ptr, which is used for special scenarios with shared_ptr as I understand.
A fair comment would be that this class actually does nothing, that a normal pointer would do and this is true.
However, I find it extremely useful, and would like it considered as an addition to boost.
It allows my code to be free of the * pointer notation.
All pointers look the same, ie shared_ptr<Foo>, scoped_ptr<Foo>, weak_ptr<Foo>
It throws an exception if it has been default constructed or set to 0, this could probably be a debug only behaviour for efficiency, but i leave it in release code.
It can be used in many places a reference would be used.
It includes constructors for many smart pointer types and from a reference to the class pointed to.
using namespace std;
struct IFoo
{
};
struct Foo : IFoo
{
};
vector<Foo> foos;
BOOST_FOREACH(weak_ptr<Foo> f,foos)
{
//do something with f->
}
vector< weak_ptr<IFoo> > weakfoos;
std::copy(foos.begin(),foos.end(),back_inserter(weakfoos));
In the above code, if vector<Foo> foos was changed to vector< shared_ptr<Foo> > the code will still work perfectly with out change.
I find this really useful because often small structs become polymorphic classes (requiring shared_ptr) as code evolves.
The vector example is the best, but even when returning a pointer to something like this it is good:
struct Bar {};
struct Foo
{
Bar mBar;
weak_ptr<Bar> bar() const { return mBar; }
};
if Bar mBar becomes scoped_ptr<Bar> mBar, the accessor still compiles.
//Definition starts here
namespace alex
{
class null_weak_ptr_exception : public std::runtime_error
{
public:
null_weak_ptr_exception() : std::runtime_error("null_weak_ptr_exception : dereferencing null pointer") {}
};
template <typename T>
class weak_ptr
{
private:
T * p;
public:
weak_ptr() : p(0) {}
weak_ptr(weak_ptr const & x) : p(x.p) {}
weak_ptr & operator=(weak_ptr const & x)
{
p = x.p;
return *this;
}
weak_ptr(T * p) : p(p) {}
weak_ptr(T & ref) : p(&ref) {}
template<class Y> weak_ptr(const alex::weak_ptr<Y> & y)
: p(y.get())
{
}
template<class Y> weak_ptr(const std::auto_ptr<Y> & y)
: p(y.get())
{
}
template<class Y> weak_ptr(const boost::shared_ptr<Y> & y)
: p(y.get())
{
}
template<class Y> weak_ptr(const boost::scoped_ptr<Y> & y)
: p(y.get())
{
}
template<class Y> weak_ptr(const alex::aggregate_ptr<Y> & y)
: p(y.get())
{
}
T & operator*() const
{
if (!p) throw null_weak_ptr_exception();
return *p;
}
T * operator->() const
{
if (!p) throw null_weak_ptr_exception();
return p;
}
T * get() const
{
return p;
}
};
template <typename T>
bool operator == (const weak_ptr<T> & x,const weak_ptr<T> & y)
{
return x.get() == y.get();
}
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk