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

5 篇文章 0 订阅

一 函数指针:

        顾名思义,函数指针即指向函数之指针,它与其他普通类型指针一样,所占内存为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.h
class Newspaper : public QObject
{
    Q_OBJECT
public:
    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_OBJECT
public:
    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的信号槽中的使用,部分代码取自互联网,感谢分享。还有一些其他细节就不在此展开了,请自行查阅,见谅!

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Qt中,信号是一种用于对象间通信的机制。信号是对象发出的事件,而是对这些事件进行响应的函数。当一个信号被触发时,与之相连接的函数将会被调用。 在Qt中,信号函数可以具有不同的参数型。当信号函数的参数型不匹配时,Qt会自动进行型转换。但是,如果你需要传递额外的参数给函数,你可以使用信号函数指针参数。 具体来说,你可以在信号函数的定义中使用指针参数。当信号被触发时,可以通过指针参数传递额外的数据给函数。这样,函数就可以根据传递的数据进行相应的处理。 下面是一个示例代码,演示了如何在Qt中使用信号函数指针参数: ```cpp class MyObject : public QObject { Q_OBJECT public: MyObject(QObject *parent = nullptr) : QObject(parent) {} signals: void mySignal(int value, QString text); public slots: void mySlot(int value, QString text) { // 处理传递过来的参数 qDebug() << "Received value:" << value; qDebug() << "Received text:" << text; } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); MyObject obj; // 连接信号函数 QObject::connect(&obj, &MyObject::mySignal, &obj, &MyObject::mySlot); // 触发信号,并传递参数 emit obj.mySignal(42, "Hello, world!"); return app.exec(); } ``` 在上面的示例中,`mySignal`信号带有两个参数:一个整数和一个字符串。`mySlot`函数也带有相同的参数。通过使用信号函数指针参数,我们可以将信号的参数传递给函数进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值