The Qt signals/slots and property system are based on the ability to introspect the objects at runtime.
C++ does not offer introspection support natively, so Qt comes with a tool to provide it. That tool is MOC.
It parses the header files and generates an additional C++ file that is compiled with the rest of the program
(1) signals, slots fucntion are simple functions, but MOC will see them
(2) Q_OBJECT defines a bunch of functions and a static QMetaObject, all signals/connections are stored here
we can get the deatails about it from https://woboq.com/blog/how-qt-signals-slots-work.html
write one very simple and similar example that implements signala and slot:
// file :QObject.h #include<map> #define SIGNAL int #define SLOT void #define CONNECT(ObjectA,signal,ObjectB,slot) ObjectA.getMeta()->connection.insert(std::pair<int,void*>(signal,(void*)new Caller(ObjectB,slot))) #define EMIT(ObjectA,signal) ObjectA.activate(signal) class Caller { public: class icaller{ public:virtual void run() = 0; }; template<class T> class caller :public icaller { public: caller(T * obj, void(T::*call)()) :object(obj), func(call){} virtual void run(){ (object->*func)(); } T * object; void(T::*func)(); }; template<class T> Caller(T*object, void (T::*clk)()){ p = new caller<T>(object, clk); } icaller * p; void run() { p->run(); } }; struct QmetaObject { std::map<int, void*> connection; }; class QObject { public: QmetaObject * getMeta(){ return &metadata; } // we can create a new thread, queue the caller void activate(int sig){ Caller * pfunc = (Caller*)getMeta()->connection.at(sig); pfunc->run(); } private: // metadata QmetaObject metadata; };
the functionality of class Caller see here:http://www.cnblogs.com/resibe-3/p/6639151.html
#include"QObject.h" #include<iostream> class myclassA : public QObject{ public: myclassA() :A(1){} SIGNAL A; }; class myclassB : public QObject{ public: SLOT B(){ std::cout << " function B was called" << std::endl;} }; void callback(){ myclassB bb; bb.B(); } void pushbutton(myclassA aa){ // suppose we push an button aa, // if we adopt signal-slot mechanism, it will emit a signal here EMIT(aa, aa.A); // if we use callback,then // callback(); } int main() { myclassA aa; myclassB bb; CONNECT(aa, aa.A, &bb, &myclassB::B); pushbutton(aa); }