如何使C++增强::信号从封装发出它的物体的物体中捕获
How to make a C++ boost::signal be caught from an object which encapsulates the object which emits it?
我有一个TcpDevice类,它封装了一个TCP连接,它有一个onRemoteDisconnect 方法,每当远程端挂断时就会被调用。然后,有一个 SessionManager 对象,该对象创建 TcpSession 对象,这些对象将 TcpDevice 作为通信通道,并将它们插入内部指针容器中供应用程序使用。如果任何托管 TcpSession 应该结束,我希望 SessionManager 实例收到有关它的通知,然后从容器中删除相应的会话,从而释放与其关联的资源。
我发现我的问题与这个问题非常相似:
对象从容器中删除自身
但是由于他有一个用于检查连接状态的线程,它与我的以及我打算使用 boost::signals 解决它的方式略有不同,所以我决定去找一个针对它的新问题 - 如果这是错误的方法,我深表歉意......我仍然对如何正确使用SO:)有所了解
由于我对QT信号/插槽有点熟悉,我发现boost::signals提供了类似的机制(我已经在使用boost::asio并且在这个项目中没有QT),所以我决定实现一个remoteDevice断开连接的信号由TcpDevice的onRemoteDisconnect发出,并且我将在SessionManager中有一个插槽。,然后从容器中删除断开连接的会话和设备。
为了初步尝试,我在tcpdevice.hpp中将信号声明为TcpDevice的公共成员:
class TcpDevice
{
(...)
public:
boost::signal <void ()> remoteDeviceDisconnected;
(...)
}
然后我从TcpDevice的onRemoteConnect方法发出它,如下所示:
remoteDeviceDisconnected();
现在,有没有办法从会话管理器内部将此信号连接到我的会话管理器插槽?我试过这个:
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->remoteDeviceDisconnected.connect(boost::bind(&SessionManager::removeDeadSessionSlot, this));
return session_id;
}
它编译得很好,但在链接时它抱怨远程设备的多个定义在几个目标代码文件中断开连接:
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
我觉得这很奇怪,因为我没有在任何地方重新定义信号,而只是在上面的createSession方法中使用它。
任何提示将不胜感激!谢谢!
我的坏!就像我们都应该期待的那样,链接器是对的......确实有第二个定义,我只是无法立即发现它,因为它不是由我的任何类定义的,而只是"浮动"在我的一个.cpp文件周围,就像在 boost::signals 示例中找到的那些一样。
只是为了记录,最初的想法就像一个魅力:当给定的TcpDevice与远程端断开连接时,它会发出remoteDevice断开连接的信号,然后由SessionManager对象捕获,该对象保存指向该TcpDevice的TcpSession实例。收到通知后,SessionManager 的方法removeDeadSessionSlot 将执行,遍历容器ptr_list会话并删除断开连接的会话:
void SessionManager::removeDeadSessionSlot()
{
boost::mutex::scoped_lock lock(sessions_mutex);
TcpSession_ptr_list_it it = sessions.begin();
while (it != sessions.end()) {
if (!(*it).device->isConnected())
it = sessions.erase(it);
else
++it;
}
}
希望这可以作为某人的参考!
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- std::vector的包装器,使数组的结构看起来像结构的数组
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 找到两对数字,使它们的乘积的绝对差最小化
- C++:如何使函数只返回作为列表一部分的字符串
- Python中的for循环与C++有何不同
- c++使用foreach使数组为null
- 使外部项目可用于find_package CMake
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 是否可以在C++中使变量真正只读
- 有可能使shared_ptr协变吗
- 使lambda不可复制/不可移动
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 如何使用OpenMP使这个循环并行
- 根据变量使Qt UI中的复选框为已选中/未选中
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- 如何使基类的运算符对基类的可变参数数可见(请参阅下面的代码)?
- 通过交换元素使数组相同
- C++11编译器何时会使RVO和NRVO优于移动语义和常量引用绑定