Boost logo

Boost Users :

Subject: [Boost-users] shared_ptr, auto_ptr and enable_shared_from_this confusion
From: Ryan McConnehey (mccorywork_at_[hidden])
Date: 2009-03-13 16:29:49


I'm having some trouble with using shared_ptr, auto_ptr and
enable_shared_from_this with my inheritance layout. The following is
how my inheritance is laid out.

// Inheritance Layout
//
// boost::enable_shared_from_this<T>
// ^
// |
// Base --------> IBase
// ^
// |
// Derived -----> IDerived

In my test code (that I've included with this email) the following two
ways to instantiate a shared pointer is equivalent.

boost::shared_ptr<IDerived> r (new Derived());

std::auto_ptr<IDerived> k (new Derived);
boost::shared_ptr<IDerived> l (k.release());

When creating the shared_ptr, both declaration take me to line 185 of
shared_ptr.hpp. Instantiating the shared_ptr directly then takes me to
line 105 of shared_ptr.hpp. Though when instantiating by releasing the
auto_ptr into the shared_ptr I'm taken to line 129. It seems to me that
I should be going to the same line of code. This wouldn't be such a
problem except when trying to call shared_from_this() an exception is
thrown if my shared_ptr was created from an auto_ptr. Is this behavior
correct?

Ryan


#include <iostream>
#include <memory>

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

// Inheritance Layout
//
// boost::enable_shared_from_this<T>
// ^
// |
// Base --------> IBase
// ^
// |
// Derived -----> IDerived

class IBase
{
public:
  virtual void hello(void) = 0;
};

class Base : public IBase, public boost::enable_shared_from_this<Base>
{
public:
  Base(void){}
  ~Base(void){}

  void hello(void)
  {
    std::cout << "Hello" << std::endl;
  }
};

class IDerived
{
public:
  virtual void world(void) = 0;

  static std::auto_ptr<IDerived> createAuto(void);
  static boost::shared_ptr<IDerived> createShared(void);

  virtual boost::shared_ptr<Base> root(void) = 0;
  virtual boost::shared_ptr<IBase> root2(void) = 0;
};

class Derived : public IDerived, public Base
{
public:
  Derived(void){}
  ~Derived(void){}

  void world(void)
  {
    std::cout << "World" << std::endl;
  }

  virtual boost::shared_ptr<Base> root(void)
  {
    return shared_from_this();
  }

  virtual boost::shared_ptr<IBase> root2(void)
  {
    return shared_from_this();
  }
};

std::auto_ptr<IDerived> IDerived::createAuto(void)
{
  return std::auto_ptr<IDerived>(new Derived());
}

boost::shared_ptr<IDerived> IDerived::createShared(void)
{
  return boost::shared_ptr<IDerived>(new Derived());
}

int main(int argc, char* argv[])
{
  boost::shared_ptr<IDerived> c = IDerived::createShared();
  boost::shared_ptr<IBase> d = c->root2();

  std::cout << c.use_count() << std::endl;

  boost::shared_ptr<IDerived> r (new Derived());

  std::auto_ptr<IDerived> k (new Derived);
  boost::shared_ptr<IDerived> l (k.release());

  boost::shared_ptr<IBase> m = l->root2();
  std::cout << m.use_count() << std::endl;

  return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net