【问题标题】:Public boost::signal object公共提升::信号对象
【发布时间】:2010-10-07 15:29:18
【问题描述】:

我公开我的boost::signals 因为我很懒。

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

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

... 而不是用Button::OnClicked(boost::function&lt;void()&gt;) 封装。

这会回来咬我吗?

【问题讨论】:

    标签: c++ boost-signals public-fields


    【解决方案1】:

    这取决于。

    每次一个对象连接到另一个对象的信号时,我都想添加一些特殊的逻辑,这让我很苦恼。这是最有可能咬你的情况。

    此外,当其他对象连接到任何给定对象时,很难准确跟踪。

    为了安全起见,我会说将连接隐藏在函数后面。

    我通常使用宏来定义 vanilla 函数。

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

    然后在类定义中:

    SIGNAL(void(),clicked)
    

    这假设您遵循命名信号“_clicked”的约定,但您可以替换任何约定。它通常使所有类的界面更干净。当您想添加特殊的连接逻辑时,您可以在不更改使用该信号的所有其他对象的情况下。

    编辑

    一个实例是信号对象实际移动到另一个类中的委托实现时,但对象通过原始类连接仍然有意义。这破坏了所有试图连接到它的地方。如果他们一直在使用函数访问器进行连接,那么就像更改函数以在委托中查找信号一样简单。但是因为它破坏了原始类的所有用户。

    或者,当我想记录每次连接到特定信号的东西时。这仅用于调试目的,但如果您怀疑信号连接中的循环等异常情况正在发生,它会非常有用。

    【讨论】:

    • 谢谢;你能告诉我一个你需要这个的具体案例吗?
    【解决方案2】:

    我偶然发现了一个很好的理由这样做。

    我们正在考虑使用在外部接口上公开 boost::signals 的第三方库。这个库依赖于带有一组编译器定义的 boost 版本,这些编译器定义与我们在项目中使用的标准 Visual Studio 编译器定义二进制不兼容。每当我们尝试调用第三方库的 signal.connect 时,事情就会死掉。

    我们的解决方案是:

    1. 使用它们提供的 boost 版本重新编译我们所有的源库和依赖库。
    2. 封装升压信号并隐藏实现

    至少要考虑一些事情!

    【讨论】:

      【解决方案3】:

      嗯,这个问题真的与boost::signalfunction 无关——都是关于封装的。

      Button 类的客户是否需要完全访问clicked?如果他们应该能够做的就是订阅它,那么只允许使用 OnClicked 方法。暴露更多可能会咬你恕我直言。

      一如既往地平衡成本与收益。在这种情况下,成本非常低。如果您在我的团队中,我强烈建议您添加 OnClicked 方法。

      【讨论】:

        【解决方案4】:

        我也将它们设为公开,并使用大写字母作为其对象名称。这种方法从来没有适得其反。

        【讨论】:

          猜你喜欢
          • 2011-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多