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);
}
来源:https://www.cnblogs.com/resibe-3/p/6635803.html