【问题标题】:How to copy the slots of a boost signal如何复制升压信号的插槽
【发布时间】:2013-12-06 09:47:37
【问题描述】:

有没有办法让信号连接到插槽?即,我想将信号的槽从一个类的一个实例复制到另一个实例

我的课堂上有一个信号并遇到以下错误。这可能是因为这个类在 STL 容器中使用。

1>c:\boost_1_52_0\boost\signals\detail\signal_base.hpp(150): error C2248: 'boost::noncopyable_::noncopyable::noncopyable' : cannot access private member declared in class 'boost::noncopyable_::noncopyable'
1>          c:\boost_1_52_0\boost\noncopyable.hpp(27) : see declaration of 'boost::noncopyable_::noncopyable::noncopyable'
1>          c:\boost_1_52_0\boost\noncopyable.hpp(22) : see declaration of 'boost::noncopyable_::noncopyable'
1>          This diagnostic occurred in the compiler generated function 'boost::signals::detail::signal_base::signal_base(const boost::signals::detail::signal_base &)'
1>  test.cpp

所以,我决定放置一个复制构造函数并将信号连接到参数信号的槽,然后我得到以下错误,

1>d:\workarea\boostsignalsEx\test.h(26): error C2663: 'boost::signal1<R,T1>::connect' : 2 overloads have no legal conversion for 'this' pointer
1>          with
1>          [
1>              R=void,
1>              T1=int
1>          ]

如果我删除复制构造函数参数的 const 限定符,我会得到另一个错误..

1>d:\workarea\boostsignalsEx\test.h(40): error C2558: class 'test' : no copy constructor available or copy constructor is declared 'explicit'

这是我正在处理的示例代码

class test{
public:
boost::signal1<void, int> sig;
test(const test& t) { t.sig.connect(sig);}; 
void attach(boost::function1<void, int> f) {sig.connect(f);}
};

猜测链接信号将不起作用,因为我不确定复制构造函数参数对象是否会存活“this”对象

【问题讨论】:

    标签: c++ boost boost-signals


    【解决方案1】:

    您只需将信号连接到新目标:

    Live on Coliru

    #include <boost/signals2.hpp>
    
    typedef void(Sigature)(int);
    typedef boost::signals2::signal<Sigature> Signal;
    typedef Signal::slot_type                 SlotType;
    
    class test{
        public:
            Signal sig;
    
            test() = default;
            test(const test& other) { *this = other; };
    
            test& operator=(test const& other) { sig.connect(other.sig); return *this; }
    
            void attach(SlotType const& f)   { sig.connect(f); }
            void trigger(int i) const        { sig(i); }
    };
    
    int main()
    {
        test a, b;
        a.attach([](int i) { std::cout << "subscribed to a:      " << i << "\n"; });
        a.attach([](int i) { std::cout << "also subscribed to a: " << i << "\n"; });
    
        std::cout << "Trigger via a:\n";
        a.trigger(42);
    
        b = a;
    
        std::cout << "\nNow via b:\n";
        b.trigger(43);
    }
    

    打印

    Trigger via a:
    subscribed to a:      42
    also subscribed to a: 42
    
    Now via b:
    subscribed to a:      43
    also subscribed to a: 43
    

    【讨论】:

    • 这是一个很好的例子。但是如果在触发发送对象之前删除第一个对象,则将一个信号连接到另一个信号不起作用。 test *a = new test(), *b = new test(); a-&gt;attach([](int i) { std::cout &lt;&lt; "subscribed to a: " &lt;&lt; i &lt;&lt; "\n"; }); a-&gt;attach([](int i) { std::cout &lt;&lt; "also subscribed to a: " &lt;&lt; i &lt;&lt; "\n"; }); std::cout &lt;&lt; "Trigger via a:\n"; a-&gt;trigger(42); (*b) = (*a); delete a; std::cout &lt;&lt; "\nNow via b:\n"; b-&gt;trigger(43); 输出为 Trigger via a: subscribed to a: 42 also subscribed to a: 42 Now via b:
    【解决方案2】:

    Boost 信号在设计上是不可复制的,因此不能在 STL 容器中使用。如Blog 中所述,可以使用指向信号的指针。

    信号是可移动的,可以在 c++11 容器中使用。

    【讨论】:

      猜你喜欢
      • 2019-04-20
      • 1970-01-01
      • 1970-01-01
      • 2012-09-11
      • 2012-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多