C++ slot signal机制

一、C++ slot signal机制的一个简单实现

 出处:http://blog.csdn.net/hhyttppd/article/details/4192668

       

  1. #include <iostream>   
  2. #include <vector>   
  3. #include <functional>   
  4. #include <algorithm>   
  5. using namespace std;  
  6. class A{  
  7. public:  
  8.     void Clicked(int id)  
  9.     {  
  10.         cout << "A::Clicked" << endl;     
  11.     }  
  12. };  
  13. class B{  
  14. public:  
  15.     void Clicked(int id)  
  16.     {  
  17.         cout << "B::Clicked" << endl;     
  18.     }  
  19. };  
  20. class SlotBase{  
  21. public:  
  22.     virtual void OnSignal(int id) = 0;  
  23. };  
  24. template<class T>  
  25. class Slot : public SlotBase{  
  26. public:  
  27.     typedef void (T::*MemberFuncType)(int);   
  28.     Slot(T* obj, MemberFuncType func)  
  29.         :obj_(obj), func_(func)  
  30.     {  
  31.     }  
  32.       
  33.     virtual void OnSignal(int id)  
  34.     {  
  35.         (obj_->*func_)(id);  
  36.     }  
  37. private:  
  38.     T* obj_;  
  39.     MemberFuncType func_;  
  40. };  
  41. template<class T>  
  42. SlotBase* MakeSlot(T * p, void (T::*func)(int))  
  43. {  
  44.     return new Slot<T>( p, func ) ;   
  45. }  
  46. class Signal  
  47. {  
  48. public:  
  49.     virtual ~Signal()  
  50.     {  
  51.         std::for_each(slots_.begin(), slots_.end(), SignalDelete());  
  52.     }  
  53.     struct SignalDelete: public unary_function<SlotBase*, void>  
  54.     {  
  55.     public:  
  56.         void operator()(SlotBase*& slot) const  
  57.         {  
  58.             delete slot;  
  59.         }  
  60.     };  
  61.     struct SignalAction: public binary_function<SlotBase*, intvoid>  
  62.     {  
  63.     public:  
  64.         void operator()(SlotBase*& slot, const int& i) const  
  65.         {  
  66.             slot->OnSignal(i);  
  67.         }  
  68.     };  
  69.     void signal(int id)  
  70.     {   
  71.         std::for_each(slots_.begin(), slots_.end(), bind2nd(SignalAction(), id));  
  72.     }  
  73.     void connect( SlotBase* s)   
  74.     {  
  75.         slots_.push_back(s);   
  76.     }  
  77. protected:  
  78.     vector< SlotBase* >   slots_;  
  79. };  
  80. int _tmain(int argc, _TCHAR* argv[])  
  81. {  
  82.     A a;  
  83.     B b;  
  84.     Signal signal;  
  85.     signal.connect(MakeSlot(&a, &A::Clicked));  
  86.     signal.connect(MakeSlot(&b, &B::Clicked));  
  87.     signal.signal(1);  
  88.     return 0;  
  89. }  

    但是这个实现明显有个潜在的问题。如果main函数是

 

int _tmain(int argc, _TCHAR* argv[])  

{  

       Signal signal; 

      {

             A a;  

             B b;  

             signal.connect(MakeSlot(&a, &A::Clicked));  

            signal.connect(MakeSlot(&b, &B::Clicked));  

      }

       signal.signal(1);  //这里a、b已经析构了。

      return 0;  

 

有空将提供一个更加可靠的实现。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在 C 语言中,通常使用回调函数来实现 signal slot 机制。 示例如下: ``` #include <stdio.h> #include <signal.h> void signal_handler(int signal) { printf("received signal %d\n", signal); } int main(int argc, char* argv[]) { // 设置信号处理函数 signal(SIGINT, signal_handler); // 暂停程序,等待信号 pause(); return 0; } ``` 运行上述代码后,如果按下 Ctrl+C 键,将会触发 SIGINT 信号,从而调用 signal_handler 函数。 如果想要实现更类似于传统意义上的 signal slot 机制,可以使用宏来模拟连接和断开连接操作。 示例如下: ``` #define connect(signal, slot) signal = slot #define disconnect(signal, slot) signal = NULL void signal_handler(int signal) { printf("received signal %d\n", signal); } int main(int argc, char* argv[]) { // 连接信号和槽 connect(SIGINT, signal_handler); // 暂停程序,等待信号 pause(); // 断开信号和槽 disconnect(SIGINT, signal_handler); return 0; } ``` 运行上述代码后,Ctrl+C 键会触发 SIGINT 信号,从而调用 signal_handler 函数。如果断开了连接,则不会再调用 signal_handler 函数。 ### 回答2: C语言是一种广泛应用于系统开发和嵌入式领域的编程语言,它为开发人员提供了灵活且高效的工具。在C编程中,`connect`函数常用于实现信号槽(signal slot机制。 信号槽是一种常见的事件处理机制,用于模块间的通信和协同工作。在C语言中,我们可以通过自定义结构体或函数指针来实现信号槽机制。下面是一个示例代码,演示了如何使用`connect`函数实现信号槽机制: ```c #include <stdio.h> #include <stdlib.h> #include <signal.h> typedef void (*SignalHandler)(int); typedef struct { SignalHandler handler; } Slot; void connect(int signal, Slot slot) { signal(signal, slot.handler); } void onSignal(int signal) { printf("Received signal: %d\n", signal); } int main() { Slot slot; slot.handler = onSignal; connect(SIGINT, slot); printf("Press Ctrl+C to send a signal...\n"); while (1) { // 无限循环,等待信号发送 } return 0; } ``` 在上述示例中,我们定义了一个`Slot`结构体,其中包含一个函数指针`handler`,用于存储信号处理函数的地址。`connect`函数用于将信号和信号槽连接起来,它使用`signal`函数将指定的信号与信号槽中的处理函数关联起来。 在`main`函数中,我们创建了一个`Slot`对象`slot`,并将`onSignal`函数赋值给了`slot.handler`。然后,通过调用`connect`函数将`SIGINT`信号与`slot`连接起来,使得当收到`SIGINT`信号时,会自动调用`onSignal`函数。 最后,在程序中无限循环,等待信号的到来。当按下Ctrl+C时,系统会发送SIGINT信号,`onSignal`函数会被调用,输出相应的信息。 通过以上示例,我们可以看到使用`connect`函数可以实现信号槽机制。这种机制在各类事件驱动的应用中非常有用,可以实现模块间的松耦合和高效的消息传递。 ### 回答3: 在C语言中,要实现类似C++中的信号槽(signal slot机制,可以使用`connect`函数来连接信号和槽函数。 首先,我们需要定义信号和槽函数的原型。信号函数通常没有返回值,而槽函数可以有任意类型的返回值。以下是一个示例的信号和槽函数原型: ```c typedef void(*signal_t)(void); typedef void(*slot_t)(void); ``` 接下来,我们定义一个结构体来表示一个信号与槽函数的对应关系: ```c typedef struct { signal_t signal; slot_t slot; } connection_t; ``` 然后,我们可以定义一个数组来保存所有的信号与槽函数的连接关系: ```c #define MAX_CONNECTIONS 10 connection_t connections[MAX_CONNECTIONS]; int num_connections = 0; ``` 接下来,我们需要实现`connect`函数。这个函数接受一个信号函数和一个槽函数作为参数,并将它们连接起来: ```c void connect(signal_t signal, slot_t slot) { if (num_connections < MAX_CONNECTIONS) { connections[num_connections].signal = signal; connections[num_connections].slot = slot; num_connections++; } } ``` 最后,我们可以实现一个函数来调用信号函数并依次调用与之连接的槽函数: ```c void emit(signal_t signal) { for (int i = 0; i < num_connections; i++) { if (connections[i].signal == signal) { connections[i].slot(); } } } ``` 现在,我们就可以通过`connect`函数来连接信号和槽函数了。当我们调用`emit`函数来触发信号时,所有与之连接的槽函数都会依次被调用。 以上是一个简单的示例,通过`connect`函数实现了信号槽机制。这个示例可以用于实现观察者模式、事件处理等需要在不同部分之间进行通信的情况。当然,实际应用可能需要更多的功能和细节处理,请根据具体需求进行扩展和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值