$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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;
}