class CBaseClass { //приватные данные для этого класса int private_base_data; {virtual?} void click(ClassA * param) = 0;//сигнатура обработчика QHash<QString,click> hash; void registerClick(QString name, click func) { hash[name]=func; } void callClick(QString name, ClassA * objectA) { click func = hash.value(name); if(func) func(objectA); }};
class CDerivedClass : public CBaseClass { int private_derived_data; void click1(ClassA * param); void click2(ClassA * param); ... void clickN(ClassA * param);};class CDerivedClass2 : public CDerivedClass { int private_derived2_data; void click2_1(ClassA * param); ... void click2_N(ClassA * param);};
gcc:QMAKE_CXXFLAGS += -std=c++11
class QRailItem; //графический элемент на сценеclass CBaseController { typedef std::function<void(QRailItem*)> ClickHandlerFunc; QHash<QString,ClickHandlerFunc> fclickHahdlers;protected: void setClickHandlerForButton(const QString & role, ClickHandlerFunc handler);private slots: void handleViewItemClick(); //обработка нажатия на граф.объект};void CBaseController ::setClickHandlerForButton(const QString &role, CRailController::ClickHandlerFunc handler){ fclickHahdlers[role] = handler;}void CRailController::handleViewItemClick(){ QRailItem * railItemView = qobject_cast<QRailItem*>(sender()); //получаем отправителя if(railItemView && railItemView->controllerLink()) //если есть { try { ClickHandlerFunc func = fclickHahdlers.value(railItemView->referenceRole()); if(func) func(railItemView); } catch(std::bad_function_call call) { qDebug("bad function call %s",call.what()); } }}
class CDerivedController : public CBaseController{ void sendCommandI(QRailItem *eventSource); void sendCommandOI(QRailItem *eventSource); void sendCommandZP(QRailItem *eventSource);}CDerivedController::CDerivedController():CBaseController(){ ClickHandlerFunc f = std::bind(&CRailCrossController::sendCommandI);//ругатется здесь setClickHandlerForButton(iBtnRole,f);}
C++ (Qt)#include <QtCore>#include <QDebug> struct Base { typedef void (Base::*MemberFunc)( int ); Base( void ) { mHash["DoPrn"] = &Base::DoPrn; } virtual void DoPrn( int val ) { qDebug() << "Base DoPrn" << val; } void CallByName( const QString & name, int val ) { MemberFunc func = mHash.value(name); if (func) (this->*func)(val); } QHash<QString, MemberFunc> mHash;}; struct Derived : public Base { virtual void DoPrn( int val ) { qDebug() << "Derived DoPrn" << val; }}; int main(int argc, char *argv[]){ (void) argc; (void) argv; Derived test; test.CallByName("DoPrn", 5); return 0;}
C++ (Qt)using namespace std::placeholders; class base{public: template <class T, class M> void register_delegate(const std::string & name, T *obj, M delegate) { _map[name] = std::bind(delegate, obj, _1, _2); } void run(const std::string & name, int a, int b) { _map[name](a, b); } private: std::map<std::string, std::function<void(int, int)>> _map;}; class derived : public base{public: void delegate(int a, int b) { std::cout << "derived::delegate(int a, int b); a + b = " << a + b << std::endl; } void delegate2(int a, int b) { std::cout << "derived::delegate2(int a, int b); a * b = " << a * b << std::endl; }}; derived d; d.register_delegate("id1", &d, &derived::delegate); d.register_delegate("id2", &d, &derived::delegate2); d.run("id1", 1, 2); d.run("id2", 1, 2);