Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to make a C++ boost::signal be caught from an object which encapsulates the object which emits it?
    text
    copied!<p>I have a <strong>TcpDevice</strong> class which encapsulates a TCP connection, which has an <em>onRemoteDisconnect</em> method which gets called whenever the remote end hangs up. Then, there's a <strong>SessionManager</strong> object which creates <strong>TcpSession</strong> objects which take a <strong>TcpDevice</strong> as a communication channel and inserts them in an internal pointer container for the application to use. In case any of the managed <strong>TcpSessions</strong> should end, I would like the <strong>SessionManager</strong> instance to be notified about it and then remove the corresponding session from the container, freeing up the resources associated with it.</p> <p>I found my problem to be very similar to this question:</p> <p><a href="https://stackoverflow.com/q/862093/1007502">Object delete itself from container</a></p> <p>but since he has a thread for checking the connections state, it gets a little different from mine and the way I intended to solve it using <em>boost::signals</em>, so I decided to go for a new question geared towards it - I apologize if it's the wrong way to do it... I'm still getting the feel on how to properly use S.O. :)</p> <p>Since I'm kind of familiar with QT signals/slots, I found <strong>boost::signals</strong> offers a similar mechanism (I'm already using <em>boost::asio</em> and have no QT in this project), so I decided to implement a <strong><em>remoteDeviceDisconnected</em></strong> signal to be emitted by <strong>TcpDevice's</strong> <em>onRemoteDisconnect</em>, and for which I would have a slot in <strong>SessionManager</strong>, which would then delete the disconnected session and device from the container.</p> <p>To initially try it out I declared the signal as a public member of <strong>TcpDevice</strong> in <em>tcpdevice.hpp</em>:</p> <pre><code>class TcpDevice { (...) public: boost::signal &lt;void ()&gt; remoteDeviceDisconnected; (...) } </code></pre> <p>Then I emitted it from <strong>TcpDevice's</strong> <em>onRemoteDisconnect</em> method like this:</p> <pre><code>remoteDeviceDisconnected(); </code></pre> <p>Now, is there any way to connect this signal to my <strong>SessionManager</strong> slot from <strong><em>inside</em></strong> session manager? I tried this:</p> <pre><code>unsigned int SessionManager::createSession(TcpDevice* device) { unsigned int session_id = session_counter++; boost::mutex::scoped_lock lock(sessions_mutex); sessions.push_back(new TcpSession(device, session_id)); device-&gt;remoteDeviceDisconnected.connect(boost::bind(&amp;SessionManager::removeDeadSessionSlot, this)); return session_id; } </code></pre> <p>It compiles fine but at link time it complains of multiple definitions of <em>remoteDeviceDisconnected</em> in several object code files:</p> <pre><code>tcpsession.cpp.o:(.bss+0x0): multiple definition of `remoteDeviceDisconnected' tcpdevice.cpp.o: (.bss+0x0): first defined here sessionmanager.cpp.o:(.bss+0x0): multiple definition of `remoteDeviceDisconnected' tcpdevice.cpp.o: (.bss+0x0): first defined here </code></pre> <p>I found this strange, since I didn't redefine the signal anywhere, but just used it at the <em>createSession</em> method above.</p> <p>Any tips would be greatly appreciated! Thank you!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload