Boost logo

Boost :

Subject: [boost] Weak pointer to object not managed by a shared_ptr
From: Mateusz Loskot (mateusz_at_[hidden])
Date: 2009-09-02 11:58:30


Hi,

One of the smart pointer techniques [1] explains use of weak_ptr
pointer to object not managed by a shared_ptr.

[1] http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/sp_techniques.html

I'm wondering what would be practical use case of that?
Is it a part of any of known idioms or patterns?

Also, is it valid to assume that this technique can extend lifetime of X
so of the internal integral X::i_ ?

Here is a simple test case based on the technique explained in the
smartptr docs [1] with my questions marked using XXX tag:

/// begin of program ///////////////////////////////////////////////
#include <exception>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
using namespace std;
using namespace boost;

struct null_deleter
{
    void operator()(void const *) const { std::cout << "deleter\n"; }
};

class X
{
public:
    explicit X(int i): this_(this, null_deleter()), i_(i) {}
    X(X const & rhs): this_(this, null_deleter()), i_(rhs.i_) {}
    X & operator=(X const & rhs) { i_ = rhs.i_; return *this; }
    weak_ptr<X> get_weak_ptr() const { return this_; }
    int get_i() const { return i_; }
private:
    shared_ptr<X> this_;
    int i_;
};

int main()
{
    try
    {
        shared_ptr<X> spx;
        {
            X x1(7);

            // XXX: lifetime is extended here?
            spx = shared_ptr<X>(x1.get_weak_ptr());
        }

        // XXX: No exception. x1 is still alive, so the pointer valid?
        cout << spx->get_i() << std::endl;
    }
    catch (bad_weak_ptr const& e) { cerr << e.what() << endl; }
    catch (exception const& e) { cerr << e.what() << endl; }
    catch (...) { cerr << "unknown error\n"; }
    return 0;
}
/// end of program ///////////////////////////////////////////////

No exception is thrown and I can
It seem that the lifetime of x1, automatic object, has been extended
beyond its "natural" scope. Am I correct?

However, if I replace retrival of shared_ptr with weak_ptr then of
course bad_weak_ptr exception is thrown:

shared_ptr<X> spx;
weak_ptr<X> wpx;
{
    X x1(7);
    wpx = x1.get_weak_ptr();
}
spx = shared_ptr<X>(wpx);
cout << spx->get_i() << std::endl;

I'm having problems with understanding of what causes the extention of
lifetime of X (so of internal X::i_ object).
Is this mechanism similar to binding r-value to "const reference"?

I would appreciate if anyone could help me to understand it.
References to the C++ standard would be great too.

Best regards,

-- 
Mateusz Loskot, http://mateusz.loskot.net
Charter Member of OSGeo, http://osgeo.org

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk