The signal slot technology has been around for a long time. I have long heard of a large number of applications in QT and have never studied it together. I recently used libjingle and read related articles and code.
It uses the template technology to decouple the message producer -- trigger signal object and the consumer -- receiver signal object (slot), which simplifies the code.
Similar Technologies commonly use callback, such as typical event and dispatch loop, onevent, onconnect, and other callback methods.
When the set signal is generated, the producer object calls the callback method of the consumer object, which is obviously not as flexible as the signal slot in implementation.
Let the code speak without talking nonsense
General statement
#include <stdio.h>#include <stdlib.h>#include <string>#include <iostream>#include "sigslot.h"using namespace std;using namespace sigslot;//example 0class CSwitch{public: virtual void Clicked() = 0;};class CLight{public: CLight():state(false) {} void ToggleState() { state = !state; } void TurnOn() { state=true; }; void TurnOff() { state=false; }; void printState() { if(state) printf("on\n"); else printf("off\n"); }private: bool state;};class ToggleSwitch : public CSwitch{public: ToggleSwitch(CLight& lp):m_lp(lp) {} virtual void Clicked() { m_lp.ToggleState(); }private: CLight& m_lp;};#ifdef __TEST_SIGSLOT__int main(int argc, char* argv[])#elseint sigslot_usage(int argc, char* argv[])#endif{ //example 1 CLight lp1, lp2; CSwitch* pSw1 = new ToggleSwitch(lp1); CSwitch* pSw2 = new ToggleSwitch(lp2); lp1.printState(); pSw1->Clicked(); lp1.printState(); lp2.printState(); pSw2->Clicked(); lp2.printState(); delete pSw1; delete pSw2; return 0;}
--- Output ---
Off
On
Off
On
Using the signal slot written as follows, which use sigslot. h from the http://sigslot.sourceforge.net/, very useful signal slot library, on a header file
Example 1
#include <stdio.h>#include <stdlib.h>#include <string>#include <iostream>#include "sigslot.h"using namespace std;using namespace sigslot;//example 1class Switch{public:void execute() {Clicked();}signal0<> Clicked;};class Light : public has_slots<>{public: Light():state(false) {}void ToggleState() {state = !state; } void TurnOn() { state=true; };void TurnOff() { state=false; };void printState() { if(state) printf("on\n");else printf("off\n");}private:bool state;};#ifdef __TEST_SIGSLOT1__int main(int argc, char* argv[])#elseint sigslot_usage1(int argc, char* argv[])#endif{ //example 1Switch sw1, sw2;Light lp1, lp2;sw1.Clicked.connect(&lp1, &Light::ToggleState);sw2.Clicked.connect(&lp2, &Light::ToggleState);lp1.printState();sw1.execute();lp1.printState();lp2.printState();sw2.execute();lp2.printState();return 0;}
--- Output ---
Off
On
Off
On
Example 2
#include <stdio.h>#include <stdlib.h>#include <string>#include <iostream>#include "sigslot.h"using namespace std;using namespace sigslot;//example 2class Sender {public:sigslot::signal2<string, std::time_t> SignalDanger; void Panic(){ SignalDanger("Help!", std::time(0)); } };class Receiver : public sigslot::has_slots<> {public:Receiver(Sender& sender) { sender.SignalDanger.connect(this, &Receiver::OnDanger);}void OnDanger(string message, std::time_t time) { if(message == "Help!") cout<<"help when "<<time<<endl;}};#ifdef __TEST_SIGSLOT2__int main(int argc, char* argv[])#elseint sigslot_usage2(int argc, char* argv[])#endif{Sender sender;Receiver receiver(sender);sender.Panic();return 0;}
--- Output ---
Help when 1350872883
The above code is organized according to the official documents. Next we should look at the internal implementation mechanism of the signal slot.