Qt学习记录--05 函数指针以及类函数指针用于Qt信号槽

来源:互联网 发布:最新淘宝打包员招聘 编辑:程序博客网 时间:2024/06/13 01:56

一 函数指针:

        顾名思义,函数指针即指向函数之指针,它与其他普通类型指针一样,所占内存为4个字节(32位系统)。所不同的是其内部存储了函数的地址而非数据地址,函数指针可以实现对参数类型参数顺序返回值都相同的函数进行封装,是多态的一种实现方式。

        其一般的使用非常简单,假如返回值为int类型,入参有两个从左到右分别为char*和int,那么声明此类函数指针如下:

int (*pFunc)(char*, int);

        假设有如下形式的函数:

int Test(char *pSz, int nCount);
        那么函数指针的使用如下:

pFunc = Test;// 亦可pFunc = &Test;

        说个更有趣的使用(秘密武器, 一般人不告诉他...):

//! 都可以pFunc = *Test;PFunc = **Test;pFunc = ***Test;//...
        实际使用一般会用typedef定义为一种类型:

typedef int (*PFUNC)(char*, int);
        使用时,需先要声明对象:

PFUNC pFunc = Test;

二 类函数指针:

        类的静态成员函数采用与一般函数指针相同的调用方式不受this指针的影响;类的非静态成员函数与一般函数指针是不兼容的。而且,不同类的this指针是不一样的,因此,指向不同类的非静态成员函数的指针也是不兼容的。指向类的非静态成员函数的指针,在声明时就需要添加类名

        类函数指针之静态成员函数:

//! 指向一般类的静态成员函数的指针定义typedef int (*pGeneralFun)(int, int);
        类函数指针之非静态成员函数:

//! 指向类的非静态成员函数的指针定义typedef int (CA::*pClassFun)(int, int);

三 类函数指针在Qt信号槽的使用:

有如下程序(照搬之):

//!!! Qt5#include <QObject>////////// newspaper.hclass Newspaper : public QObject{    Q_OBJECTpublic:    Newspaper(const QString & name) :        m_name(name)    {    }    void send() const    {        emit newPaper(m_name);    }signals:    void newPaper(const QString &name) const;private:    QString m_name;};////////// reader.h#include <QObject>#include <QDebug>class Reader : public QObject{    Q_OBJECTpublic:    Reader() {}    void receiveNewspaper(const QString & name) const    {        qDebug() << "Receives Newspaper: " << name;    }};////////// main.cpp#include <QCoreApplication>#include "newspaper.h"#include "reader.h"int main(int argc, char *argv[]){    QCoreApplication app(argc, argv);    Newspaper newspaper("Newspaper A");    Reader reader;    QObject::connect(&newspaper, &Newspaper::newPaper,                     &reader,    &Reader::receiveNewspaper);    newspaper.send();    return app.exec();}
        上面connect()函数可以正常绑定信号槽,但是信号如同普通成员函数一样也支持重载,添加如下信号:

void newPaper(const QString &name, const QDate &date);
        按照前面的写法,编译器会报出一个错误由于这个函数(注意,信号实际也是一个普通的函数)有重载,因此不能用一个取址操作符获取其地址。在 Qt 4 中,我们使用SIGNAL和SLOT两个宏来连接信号槽。如果有一个带有两个参数的信号,由于其信号槽的连接是带参数的,所以connect()函数使用Qt4的风格编写是没有问题的,代码如下:

QObject::connect(&newspaper, SIGNAL(newPaper(QString, QDate)),                 &reader,    SLOT(receiveNewspaper(QString, QDate)));
        此种场景下,之前讲述的类成员(非静态)函数指针便派上用场了:

void (Newspaper:: *newPaperNameDate)(const QString &, const QDate &) = &Newspaper::newPaper;QObject::connect(&newspaper, newPaperNameDate,                 &reader,    &Reader::receiveNewspaper);
        根本原因是,我们指明了函数类型,使编译器能够准确定位。当然你也可以直接声明(类型转换):
QObject::connect(&newspaper, (void (Newspaper:: *)(const QString &, const QDate &))&Newspaper::newPaper,                 &reader,     &Reader::receiveNewspaper);
        本文简要讲述了函数指针及其在Qt的信号槽中的使用,部分代码取自互联网,感谢分享。还有一些其他细节就不在此展开了,请自行查阅,见谅!

0 0
原创粉丝点击