C++成员函数指针

C++成员函数指针实现简单的信号槽

#include 
class ppp
{
public:
    QString a;
    void printA(void)
    {
        qDebug()<setupUi(this);

    void (ppp::*func)();
    void (ppp::*funcB)(QString);

    /* func实际上是成员函数printA在类ppp中的偏移地址,
     * funcB是printB的偏移地址,最终要根据实例对象加
     * 上基准地址*/
    func = &ppp::printA;
    funcB = &ppp::printB;
    ppp t1;t1.a = "t1";
    ppp t2;t2.a = "t2";

    /* 这里的t1.*func必须用括号括起来:(t1.*func),
     * 另外这里函数指针需要对象来引用,因为func只是
     * 偏移地址*/
    (t1.*func)(); // 输出:"t1"
    (t2.*func)(); // 输出:"t2"

    (t1.*funcB)("printB");// 输出:"t1" "printB"
    (t2.*funcB)("printB");// 输出:"t2" "printB"
}

现在利用回调函数的方式实现一个类似于Qt信号槽的功能,先利用模板函数兼容不同类:

#include 
template
void *recallMap()
{
    typedef void (T::*Func)();
    static QHash hash;
    return &hash;
}

template
void attach(QString mask, void (T::*func)())
{
    typedef void (T::*Func)();
    QHash *hashP = static_cast *>(recallMap());
    if (hashP != NULL)
    {
        hashP->insert(mask, func);
    }
}

template
void recall(T *t, QString mask)
{
    typedef void (T::*Func)();
    QHash *hashP = static_cast *>(recallMap());
    if (t != NULL && hashP != NULL && hashP->contains(mask))
    {
        (t->*(hashP->value(mask)))();
    }
}

下面是链接和调用的代码:

    ppp t1;t1.a = "t1";
    ppp t2;t2.a = "t2";
    
    attach("printA", &ppp::printA);
    attach("printC", &ppp::printC);

    recall(&t1, "printC");
    recall(&t2, "printC");

这样就可以将字符串跟函数直接关联起来,一般字符串是信号或事件,函数作为对信号或事件的响应。

你可能感兴趣的:(qt)