4

古いシグナル コードの代わりに、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 インスタンスの NameChange シグナルへの接続を削除する必要があります。

これは私が立ち往生しているところです。ConnectionList をテンプレートにして、信号と接続への参照を持つ構造体を保持するリストを使用し、その信号へのすべての接続をドロップするメソッドを追加できると思います。

しかし、これは非常に一般的なケースのようです (少なくとも私の世界では、この機能を必要とするこの 1 つのアプリに 20 個のクラスがあります)。

少なくとも、接続オブジェクトから接続された信号への参照を取得する方法はありますか?

おそらくlibsigc ++はこれをより適切に/異なる方法で処理しますか?

4

2 に答える 2

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;
};

また、自動接続管理も参照してください。

于 2011-06-07T14:13:05.530 に答える
0

自分で試したことはありませんが、ブーストのドキュメントによると

いつ切断が発生する可能性がありますか? (中級)

次のいずれかの条件が発生すると、信号/スロットの切断が発生します。

  • 接続は、接続のdisconnectメソッドを介して直接、またはシグナルのdisconnectメソッドまたはscoped_connectionのデストラクタを介して間接的に明示的に切断されます。
  • スロットによって追跡されたオブジェクトが破棄されます。
  • 信号が破壊されます。

を使用しない限りscoped_connection、シグナルとスロットの間の接続は、どちらかが破壊されるまで有効なままです。私が理解している限り、接続オブジェクトをベクトルに格納する必要はありません。今行っているように、信号をスロットに接続するだけです。

監視対象のオブジェクトが範囲外になると、接続が自動的に削除されます。

これははるかにシンプルなデザインです。

于 2011-06-07T14:46:58.653 に答える