Boost logo

Boost Users :

Subject: [Boost-users] shared_from_this - derived classes (yes, I googled)
From: Christopher Pisz (cpisz_at_[hidden])
Date: 2011-09-30 20:26:51


Please examine the following:

//-----------------------------------------------------------------------------
void TcpListener::Listen()
{
    TcpServerSideConnection::SmartPtr newConnection =
TcpServerSideConnection::Create(ioService_);

    TcpBaseSocket::SmartPtr ptr = shared_from_this();
    TcpListener::SmartPtr me = boost::dynamic_pointer_cast<TcpListener,
TcpBaseSocket>(ptr);

    /// Asynchronously accept one connection request when it occurs
    acceptor_.async_accept(newConnection->GetSocket(),
                           boost::bind(&TcpListener::OnConnectionAccepted,
                                       me,
                                       newConnection,
                                       boost::asio::placeholders::error));
}

It throws an exception, unwinds my stack and destroys my object on the
assignment of shared_from_this.

I forced at least one shared pointer to be created, by making factory methods
from base on up the class hierarchy.

I read on google that you can only use shared_from_this on ONE class type in a
class hierarchy. I did not understand the details of why.

following a peer's advice, I enabled_shared_from_this on the base class and
attempted to cast it in the derived class methods, getting the result that I
did.

I am trying to use a smart pointer here, following the example code for
boost::asio::ip::tcp, assuming that I want to ensure the instance of 'ths' is
alive between the time of the async call and the time it completes!

I do not see a way to do this when using a class hierarchy.

My base classes do similar async calls and try to handle it similarlly, so I
cannot enable_shared_from_this only on the most derived. As there is no
guarentee that only the most derived will be instantiated. I have more than 3
classes in the inheritance hierarchy, any of which could be instantiated.

TcpBase - holds the socket and a smart pointer to the io_service
TcpConnection - Adds Write and Read methods
TcpClientConnection - Adds Connect method
TcpServerConnection - Does not have connect, but can only be instantiated by a
TcpListener - Accepts connections and creates TcpServerConnections

Any of these, except the very base can be instantiated.

How do I work around this problem?


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