Boost logo

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