4

boost::signalは怠け者なので公開します。

class Button {
public:
    signal<void()> clicked;
};

int main() {
    Button btn;
    btn.clicked.connect(handleClick);
}

... でカプセル化するのではなく、Button::OnClicked(boost::function<void()>).

これは戻ってきて私を噛むつもりですか?

4

4 に答える 4

3

場合によります。

オブジェクトが別のオブジェクトの信号に接続されるたびに、特別なロジックを追加したいと思ったとき、それは以前私を悩ませました。これはあなたを噛む可能性が最も高いケースです。

また、他のオブジェクトが特定のオブジェクトに接続しているタイミングを正確に追跡することが難しくなる可能性があります。

安全のために、関数の背後にある接続を非表示にします。

私は通常、マクロを使用してバニラ関数の定義を行います。

#define SIGNAL(slot,name) connection name(function<slot> func) { return _##name##.connect(func);}

そして、クラス定義で:

SIGNAL(void(),clicked)

これは、信号「_clicked」の命名規則に従うことを前提としていますが、任意の規則に置き換えることができます。一般に、すべてのクラスのインターフェースをきれいに保ちます。シグナルを使用する他のすべてのオブジェクトを変更せずに、特別な接続ロジックを追加できます。

編集

1 つのインスタンスは、シグナル オブジェクトが実際には別のクラス内のデリゲート実装に移動されたときでしたが、オブジェクトが元のクラスを介して接続することは依然として意味がありました。これにより、接続しようとしたすべての場所が壊れました。関数アクセサーを使用して接続していた場合、関数を変更してデリゲートでシグナルを検索するのと同じくらい簡単でした。しかし、それは元のクラスのすべてのユーザーを壊しました。

または、特定の信号に何かが接続されるたびにログを記録したい場合。これはデバッグ目的のためだけのものでしたが、信号接続でサイクルなどの異常が発生している疑いがある場合に非常に役立ちます。

于 2009-02-14T15:04:00.257 に答える
2

私はこれをしない正当な理由に出くわしました。

外部インターフェイスでboost::signalsを公開するサードパーティライブラリの使用を検討しています。このライブラリは、プロジェクトで使用する標準のVisualStudioコンパイラ定義とバイナリ互換性のない一連のコンパイラ定義を備えたboostのバージョンに依存します。サードパーティライブラリのsignal.connectを呼び出そうとすると、物事は死にます。

私たちの解決策は次のいずれかです。

  1. ソースライブラリと依存ライブラリをすべて、提供されているブーストバージョンで再コンパイルします。
  2. ブースト信号をラップし、実装を非表示にします

少なくとも考慮すべきことがあります!

于 2012-01-12T06:42:59.290 に答える
0

まあ、この質問は本当にカプセル化に関するものでboost::signalはありません。function

Buttonクラスのクライアントは に完全にアクセスする必要がありますclickedか? 彼らがそれを購読することだけができるはずであるなら、OnClickedメソッドでそれだけを許可してください。それ以上露出すると、私見に噛まれる可能性があります。

いつものように、コストと利益のバランスをとります。この場合、コストは非常に低くなります。あなたが私のチームにいた場合は、OnClickedメソッドを追加することを強くお勧めします。

于 2009-02-15T13:35:34.647 に答える
0

それらもパブリックに設定し、オブジェクト名には大文字のキャメルケースを使用します。このアプローチが裏目に出たことはありません。

于 2009-09-19T21:10:42.170 に答える