我开始使用boost :: signals2而不是旧信号代码。我遇到了管理多个连接的问题。这是我的问题:
我有很多Person类的实例:
class Person {
public:
void SetName (string new_name)
{
name = new_name;
NameChange (name);
}
string name;
boost::signals2::signal<Person*> NameChange;
};
我还有一个人员浏览器,必须监控所有可用人员的子集以进行更改。由于人们可以从该子集进出,我必须有办法处理连接对象,并且我已经创建了一个类(ConnectionList)来处理:
class ConnectionList
{
public:
virtual ~ConnectionList () // drops all connections in "list"
void add (boost::signals2::connection& conn); // adds "conn" to "list"
private:
std::vector<boost::signals2::connection> list;
};
class PeopleBrowser
{
public:
void AddPerson (Person& p)
{
name_change_connections.add (p.NameChange.connect (...));
}
private:
ConnectionList name_change_connections;
};
这很好,当删除PeopleBrowser时会删除连接,并且有一种很好的方式来添加新连接。
但是,我们需要添加另一个方法RemovePerson,并且该方法必须删除与该Person-instance的NameChange-signal的连接。
这就是我被困住的地方。我想我可以使ConnectionList成为一个模板并使用一个包含结构的列表,该结构包含对信号和连接的引用,然后添加一个方法来删除该信号的所有连接。
但似乎这是一个常见的情况(至少在我的世界中,我在这个需要此功能的应用程序中有20个类),所以我认为必须有更好的方法来处理这个问题?
至少,有没有办法从连接对象获得对连接信号的引用?
也许libsigc ++可以更好地/不同地处理这个问题?
答案 0 :(得分:3)
怎么样:
class PeopleBrowser
{
public:
void AddPerson (Person& p)
{
name_change_connections[&p] = p.NameChange.connect(...);
}
void RemovePerson(Person& p)
{
name_change_connections.erase(&p);
}
private:
std::map<Person*, boost::signals2::scoped_connection> name_change_connections;
};
您可能还想查看automatic connection management。
答案 1 :(得分:0)
我自己没有尝试过,但根据boost documentation
什么时候可以断开连接? (中间体)强>
当出现以下任何情况时,会发生信号/插槽断开:
- 通过连接的
disconnect
方法直接或通过信号的disconnect
方法或scoped_connection
的析构函数间接断开连接。- 插槽跟踪的对象将被销毁。
- 信号被破坏。
除非您使用scoped_connection
,否则信号和插槽之间的连接将保持有效,直到它们中的任何一个被销毁。据我所知,您不需要在向量中存储连接对象。只需像现在一样将信号连接到插槽即可。
当您的观察对象超出范围时,它将自行删除连接。
这是一个更简单的设计。