【问题标题】:Boost Signals2 tracking增强 Signals2 跟踪
【发布时间】:2026-01-27 02:00:02
【问题描述】:

我在我们的一个项目中使用 Boost Signals2。在此我想要自动连接管理,为此我正在测试 Boost Signals2 跟踪,但我没有调用插槽。 在我运行以下代码后,不会调用插槽。 环境: VS 2010,windows 7,提升 1.54

    #include <stdio.h>
    #include <iostream>
    #include <string>
    #include <boost/bind.hpp>
    #include <boost/enable_shared_from_this.hpp>
    #include <boost/signals2/signal.hpp>
    #include <boost/shared_ptr.hpp>


    typedef boost::signals2::signal<void ()>  signal_test;
    using namespace boost;

    class SubjectTest
    {

    public:
        void Connect(const signal_test::slot_type &subscriber)
        {
            m_Signal.connect(subscriber);
            std::cout << "No of connections : " << m_Signal.num_slots() << std::endl;
        }
        void Notify()
        {
            m_Signal();
        }
    private:
        signal_test m_Signal;
    };

    class Listner 
    {
    public:
        Listner(){}
        ~Listner(){}
        Listner(std::string name)
        :m_name(name)
        {
        }
        void GotSignal()
        {
            std::cout << m_name <<  std::endl;
        }
        void ConnectWithTracking(SubjectTest *s)
        {
            shared_ptr<Listner> l = new Listner();
            s->Connect(signal_test::slot_type(&Listner::GotSignal,l.get()).track(l));

        }
        void ConnectNormal(SubjectTest *s)
        {
            s->Connect(bind(&Listner::GotSignal,this));

        }

    private:
        std::string m_name;
        shared_ptr<Listner> l;
    };

    void main()
    {
        Listner l2("First"); 
        SubjectTest sub;

        try
        {
        l2.ConnectWithTracking(&sub);
        //l2.ConnectNormal(&sub);
        sub.Notify();

        {
            Listner l3("Second"); 

            l3.ConnectWithTracking(&sub);
            //l3.ConnectNormal(&sub);
            sub.Notify();
        }

        sub.Notify();
        }
        catch(std::exception ex)
        {
            std::cout << ex.what() << std::endl;
        }

        std::cout << "Finish" <<std::endl;
    }

更新: *现在工作*

    #include <stdio.h>
    #include <iostream>
    #include <string>
    #include <boost/bind.hpp>
    #include <boost/enable_shared_from_this.hpp>
    #include <boost/signals2/signal.hpp>
    #include <boost/shared_ptr.hpp>


    typedef boost::signals2::signal<void ()>  signal_test;
    using namespace boost;

    class SubjectTest
    {

    public:
        void Connect(const signal_test::slot_type &subscriber)
        {
            m_Signal.connect(subscriber);
            std::cout << "No of connections : " << m_Signal.num_slots() << std::endl;
        }
        void Notify()
        {
            m_Signal();
        }
    private:
        signal_test m_Signal;
    };

    class Listner : public boost::enable_shared_from_this<Listner>
    {
    public:
        Listner(){}
        ~Listner(){}
        Listner(std::string name)
        :m_name(name)
        {
        }
        void GotSignal()
        {
            std::cout << m_name <<  std::endl;
        }
        void ConnectWithTracking(SubjectTest *s)
        {
            s->Connect(signal_test::slot_type(&Listner::GotSignal,shared_from_this().get()).track(shared_from_this()));
        }
        void ConnectNormal(SubjectTest *s)
        {
            s->Connect(bind(&Listner::GotSignal,this));
        }

    private:
        std::string m_name;

    };

    void main()
    {
        shared_ptr<Listner> l2(new Listner("First")); 

        SubjectTest sub;

        try
        {
        l2->ConnectWithTracking(&sub);

        sub.Notify();

        {
            shared_ptr<Listner> l3(new Listner("Second")); 

            l3->ConnectWithTracking(&sub);
            //l3.ConnectNormal(&sub);
            sub.Notify();
        }

        sub.Notify();
        }
        catch(std::exception ex)
        {
            std::cout << ex.what() << std::endl;
        }

        std::cout << "Finish" <<std::endl;
    }

现在这是 Signal2 自动连接管理的完整示例

【问题讨论】:

    标签: c++ boost boost-signals2


    【解决方案1】:
    {
      shared_ptr<Listner> l(new Listner());
      s->Connect(signal_test::slot_type(&Listner::GotSignal,l.get()).track(l));
    }
    

    在上述行中,l 指针在结束时被销毁 } - 这意味着您刚刚连接的插槽已过期。

    跟踪的全部意义在于将shared_ptr(或weak_ptr)传递给track(),它与插槽本身绑定(或紧密相关)。传递一个与插槽本身的生命周期无关的shared_ptr 是没有意义的。

    【讨论】:

    • 你能建议我应该在哪里创建共享指针吗?
    • @Rushikesh 你应该改变设计:从enable_shared_from_this继承Listener,使用new实例化它,并仅通过shared_ptrs管理实例。然后你就可以通过shared_from_this()track() 函数来跟踪它的生命周期。
    • 谢谢,更新的解决方案。如有错误请评论
    • @Rushikesh ,现在可以了。请注意,您不必调用shared_form_this().get(),输入this 就足够了。此外,我猜你知道ConnectNormal 是不安全的,因为缺乏跟踪。
    • 是的,ConnectNormal 用于检查信号是否正常工作。