|
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