私boost::signal
は怠け者なので公開します。
class Button {
public:
signal<void()> clicked;
};
int main() {
Button btn;
btn.clicked.connect(handleClick);
}
... でカプセル化するのではなく、Button::OnClicked(boost::function<void()>)
.
これは戻ってきて私を噛むつもりですか?
私boost::signal
は怠け者なので公開します。
class Button {
public:
signal<void()> clicked;
};
int main() {
Button btn;
btn.clicked.connect(handleClick);
}
... でカプセル化するのではなく、Button::OnClicked(boost::function<void()>)
.
これは戻ってきて私を噛むつもりですか?
場合によります。
オブジェクトが別のオブジェクトの信号に接続されるたびに、特別なロジックを追加したいと思ったとき、それは以前私を悩ませました。これはあなたを噛む可能性が最も高いケースです。
また、他のオブジェクトが特定のオブジェクトに接続しているタイミングを正確に追跡することが難しくなる可能性があります。
安全のために、関数の背後にある接続を非表示にします。
私は通常、マクロを使用してバニラ関数の定義を行います。
#define SIGNAL(slot,name) connection name(function<slot> func) { return _##name##.connect(func);}
そして、クラス定義で:
SIGNAL(void(),clicked)
これは、信号「_clicked」の命名規則に従うことを前提としていますが、任意の規則に置き換えることができます。一般に、すべてのクラスのインターフェースをきれいに保ちます。シグナルを使用する他のすべてのオブジェクトを変更せずに、特別な接続ロジックを追加できます。
編集
1 つのインスタンスは、シグナル オブジェクトが実際には別のクラス内のデリゲート実装に移動されたときでしたが、オブジェクトが元のクラスを介して接続することは依然として意味がありました。これにより、接続しようとしたすべての場所が壊れました。関数アクセサーを使用して接続していた場合、関数を変更してデリゲートでシグナルを検索するのと同じくらい簡単でした。しかし、それは元のクラスのすべてのユーザーを壊しました。
または、特定の信号に何かが接続されるたびにログを記録したい場合。これはデバッグ目的のためだけのものでしたが、信号接続でサイクルなどの異常が発生している疑いがある場合に非常に役立ちます。
私はこれをしない正当な理由に出くわしました。
外部インターフェイスでboost::signalsを公開するサードパーティライブラリの使用を検討しています。このライブラリは、プロジェクトで使用する標準のVisualStudioコンパイラ定義とバイナリ互換性のない一連のコンパイラ定義を備えたboostのバージョンに依存します。サードパーティライブラリのsignal.connectを呼び出そうとすると、物事は死にます。
私たちの解決策は次のいずれかです。
少なくとも考慮すべきことがあります!
まあ、この質問は本当にカプセル化に関するものでboost::signal
はありません。function
Button
クラスのクライアントは に完全にアクセスする必要がありますclicked
か? 彼らがそれを購読することだけができるはずであるなら、OnClicked
メソッドでそれだけを許可してください。それ以上露出すると、私見に噛まれる可能性があります。
いつものように、コストと利益のバランスをとります。この場合、コストは非常に低くなります。あなたが私のチームにいた場合は、OnClicked
メソッドを追加することを強くお勧めします。
それらもパブリックに設定し、オブジェクト名には大文字のキャメルケースを使用します。このアプローチが裏目に出たことはありません。