c++升压信号2

发布于 2024-12-05 03:52:40 字数 118 浏览 0 评论 0原文

在 C# 中,我们有 event 关键字,它是一种特殊类型的委托,只能从声明它的类中调用。那么,有没有一种方法可以使用 boost::signals2 在本机 c++ 中做到这一点,如果是这样,从性能的角度来看它是否昂贵?

In c# we have the event keyword which is an special kind of delegate which can only be invoked from withing the class that declared it. So, is there a way of doing this in native c++ using boost::signals2, if so, is it expensive from a performance stand point?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

桜花祭 2024-12-12 03:52:40

一般来说,限制 C++ 函数可调用性的方法依赖于传递无法在该类外部实例化的类型的虚拟参数(私有工厂或具有目标类的“友元”声明的构造函数)。

不过,将其应用于 boost::signals2::signal 会导致信号定义具有无关参数。

如果您确实需要使其不可调用,请记住它只是一个对象成员(至少,当我使用它时......) - 您可以将其声明为私有或受保护的成员,并提供用于连接到的公共函数它。

class FooEmitter
{
public:
    boost::signals2::scoped_connection ConnectToFoo(boost::function<void (Emitter&)>& handler)
    {
        return fooSignal.connect(handler);
    }

    void triggerFoo() {
        fooSignal(*this);
    }
private:
    boost::signals2::signal<void (Emitter&)> fooSignal;
};

class FooHandler
{
public:
    FooHandler()
    {
        fooConnection = getAnEmitter().ConnectToFoo(boost::bind(&FooHandler::HandleFoo, this, _1);
    }

    void HandleFoo(Emitter&)
    {
        // handler body
    }

private:
    boost::signals2::scoped_connection fooConnection;
}

您当然可以重新安排 ConnectToFoo 方法以获取 FooHandler&如果你的模型足够坚硬,就在那里进行绑定。

至于性能方面,通过良好的编译器,虚拟类型实际上是免费的,并且这种机制是每个处理程序(而不是每个信号)一次或两次额外的函数调用。

In general, approaches to restricting the callability a C++ function rely on passing dummy parameter of a type that either can't be instantiated outside that class (private factory or constructor with a 'friend' declaration for the intended class).

Applying this to a boost::signals2::signal would result in a signal definition that had the extraneous parameter, though.

If you really need to make it un-callable, remember that it is just an object member (at least, as I use it...) - you can declare it as a private or protected member and provide a public function for connecting to it.

class FooEmitter
{
public:
    boost::signals2::scoped_connection ConnectToFoo(boost::function<void (Emitter&)>& handler)
    {
        return fooSignal.connect(handler);
    }

    void triggerFoo() {
        fooSignal(*this);
    }
private:
    boost::signals2::signal<void (Emitter&)> fooSignal;
};

class FooHandler
{
public:
    FooHandler()
    {
        fooConnection = getAnEmitter().ConnectToFoo(boost::bind(&FooHandler::HandleFoo, this, _1);
    }

    void HandleFoo(Emitter&)
    {
        // handler body
    }

private:
    boost::signals2::scoped_connection fooConnection;
}

You could of course re-arrange the ConnectToFoo method to take a FooHandler& and do the binding in there, if your model is rigid enough.

As for the performance aspect, the dummy type is effectively free with a good compiler, and this mechanism is an additional function call or two once per handler (not per signal).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文