信号与槽中形参用法浅析

  1. 用QSharedPointer进行形参传递:

需要申请堆内存空间,以Student类为例,如下为Student类代码:

//student.h文件
#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>
#include <QDebug>
#include <QThread>
class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr,QString str = "I'm student.");
    Student(const Student& arr);
    ~Student();

public:
    QString name;
signals:

};

#endif // STUDENT_H
//student.cpp文件
#include "student.h"

Student::Student(QObject *parent,QString str) : QObject(parent),name(str)
{
    qDebug() << "Student new:" <<  "  currentId:"<< QThread::currentThreadId();
}


Student::Student(const Student& arr)
{
    this->name = arr.name;

}

Student::~Student()
{
    qDebug() <<"Student delete:"<<this->name <<"  currentId:"<< QThread::currentThreadId();
}

现在创建一个信号类 Connection2EWSignal ,负责发送信号,如下所示,在start()函数中,定义并初始化了智能指针类型的stu:

//connection2ewsignal.h
#ifndef CONNECTION2EWSIGNAL_H
#define CONNECTION2EWSIGNAL_H

#include <QObject>
#include <QThread>
#include <QDebug>
#include  "student.h"
class Connection2EWSignal : public QObject
{
    Q_OBJECT
public:
    explicit Connection2EWSignal(QObject *parent = nullptr);

signals:
    //处理接收过来的udp消息
    void dealUDPReadReadySignal(QSharedPointer<Student> aa); 
public slots:
    void start()
    {
        QByteArray arr("nihaoj;kj;lkj;lk;lkdfasfsdafasdffffsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagfdgggggggggdagfdagfdsafdsfadsfasfsdfsdfsdfsdfasdfsfsdfsadfsdfsdfsdfasfddafsafasfsafsadfsdafasdfsdfsdffddsafsdfsdfasfasfdsfsdfasdfsafasfdasdfasdfasfsdfdfsfsf111");
        //Student stu(nullptr,"funckwereretrtrtrtrtrtrtrtrtrt.");
        qDebug() <<"EWSignal:"<< QThread::currentThreadId();
        QSharedPointer<Student> stu(new Student(nullptr,"funckwereretrtrtrtrtrtrtrtrtrt."));
        emit dealUDPReadReadySignal(stu);
        qDebug() <<"EWSignalEND:"<< QThread::currentThreadId();
    }

};

#endif // CONNECTION2EWSIGNAL_H


//connection2ewsignal.cpp
#include "connection2ewsignal.h"

Connection2EWSignal::Connection2EWSignal(QObject *parent) : QObject(parent)
{

}

下面创建槽接收类Connection2EW,负责接收数据。如下代码所示:

//connection2ew.h 文件
#ifndef CONNECTION2EW_H
#define CONNECTION2EW_H

#include <QObject>
#include <QDebug>
#include <QThread>
#include "student.h"
class Connection2EW : public QObject
{
    Q_OBJECT
public:
    explicit Connection2EW(QObject *parent = nullptr);

public slots:

    //处理接收过来的udp消息
//    void dealUDPReadReady(const Student &aa)
//    {
//       QThread::sleep(1);
//       qDebug() <<"EW:"<< QThread::currentThreadId();
//       qDebug() <<"dealUDPReadReady:"<< aa.name;
//    }

    void dealUDPReadReady(QSharedPointer<Student> aa)
    {
       QThread::sleep(1);
       qDebug() <<"EW:"<< QThread::currentThreadId();
       qDebug() <<"dealUDPReadReady:"<< aa->name;
    }

    void start()
    {

    }

};

#endif // CONNECTION2EW_H


//connection2ew.cpp 文件
#include "connection2ew.h"

Connection2EW::Connection2EW(QObject *parent) : QObject(parent)
{

}

下面是main.cpp文件内容,main()函数的具体工作是注册自定义Student类型作为信号与槽可以识别的类型,然后,实例化了Connection2EW、Connection2EWSignal对象,并分别放入不同的线程,并分别启动各个线程。

#include "mainwindow.h"
#include <QThread>
#include <QApplication>
#include <QDebug>
#include "connection2ew.h"
#include "connection2ewsignal.h"
#include <QDateTime>
int main(int argc, char *argv[])
{
    qRegisterMetaType<Student>("Student");
    qRegisterMetaType<Student>("Student&");
    QApplication a(argc, argv);
    qDebug() <<"MAIN:"<< QThread::currentThreadId();
    QList<QObject*> pObjList;
    Connection2EW *pEW = new Connection2EW(nullptr);
    pObjList.append(pEW);
    Connection2EWSignal *pEWSignal = new Connection2EWSignal(nullptr);
    pObjList.append(pEWSignal);

    QObject::connect(pEWSignal,&Connection2EWSignal::dealUDPReadReadySignal,pEW,&Connection2EW::dealUDPReadReady,Qt::QueuedConnection);

    foreach(auto pObj, pObjList)
    {
        QThread* thread = new QThread();
        QObject::connect(thread, SIGNAL(started()), pObj, SLOT(start()));

        //        QObject::connect(thread, SIGNAL(finished()), pObj, SLOT(deletelater()));
        //        QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deletelater()));

        pObj->moveToThread(thread);
        thread->start();
    }

    qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss zzz");

    return a.exec();
}

程序运行后,输出:

EWSignal: 0x3a9c

Student new: currentId: 0x3a9c

EWSignalEND: 0x3a9c

"2023-02-16 10:39:39 116"

EW: 0x44d4

dealUDPReadReady: "funckwereretrtrtrtrtrtrtrtrtrt."

Student delete: "funckwereretrtrtrtrtrtrtrtrtrt." currentId: 0x44d4

根据输出可以分析出,Student类只实例化了一次,并在槽函数作用域运行结束后,这块内存释放。 

优点:相当于在指针加了一个外壳,传递的是智能指针,引用计数加一,不会再进行复制构造函数,大大降低传递过程中系统开销。

注意事项:不能强制以栈对象取地址的方式,初始化智能指针,这样会导致内存不安全。

  1. 用const Student &进行形参传递:

connection2ew.h文件更改后如下:

#ifndef CONNECTION2EW_H
#define CONNECTION2EW_H

#include <QObject>
#include <QDebug>
#include <QThread>
#include "student.h"
class Connection2EW : public QObject
{
    Q_OBJECT
public:
    explicit Connection2EW(QObject *parent = nullptr);

public slots:

    //处理接收过来的udp消息
    void dealUDPReadReady(const Student &aa)
    {
       QThread::sleep(1);
       qDebug() <<"EW:"<< QThread::currentThreadId();
       qDebug() <<"dealUDPReadReady:"<< aa.name;
    }

//    void dealUDPReadReady(QSharedPointer<Student> aa)
//    {
//       QThread::sleep(1);
//       qDebug() <<"EW:"<< QThread::currentThreadId();
//       qDebug() <<"dealUDPReadReady:"<< aa->name;
//    }

    void start()
    {

    }

};

#endif // CONNECTION2EW_H

   connection2ewsignal.h文件更改后如下:

#ifndef CONNECTION2EWSIGNAL_H
#define CONNECTION2EWSIGNAL_H

#include <QObject>
#include <QThread>
#include <QDebug>
#include  "student.h"
class Connection2EWSignal : public QObject
{
    Q_OBJECT
public:
    explicit Connection2EWSignal(QObject *parent = nullptr);

signals:
    //处理接收过来的udp消息
    //void dealUDPReadReadySignal(QSharedPointer<Student> aa);
    void dealUDPReadReadySignal(const Student &aa);
public slots:
    void start()
    {
        QByteArray arr("nihaoj;kj;lkj;lk;lkdfasfsdafasdffffsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagfdgggggggggdagfdagfdsafdsfadsfasfsdfsdfsdfsdfasdfsfsdfsadfsdfsdfsdfasfddafsafasfsafsadfsdafasdfsdfsdffddsafsdfsdfasfasfdsfsdfasdfsafasfdasdfasdfasfsdfdfsfsf111");
        Student stu(nullptr,"funckwereretrtrtrtrtrtrtrtrtrt.");
        qDebug() <<"EWSignal:"<< QThread::currentThreadId();
        //QSharedPointer<Student> stu(new Student(nullptr,"funckwereretrtrtrtrtrtrtrtrtrt."));
        emit dealUDPReadReadySignal(stu);
        qDebug() <<"EWSignalEND:"<< QThread::currentThreadId();
    }

};

#endif // CONNECTION2EWSIGNAL_H

执行程序,结果如下:

MAIN: 0x4968

Student new: currentId: 0x43f4

EWSignal: 0x43f4

EWSignalEND: 0x43f4

Student delete: "funckwereretrtrtrtrtrtrtrtrtrt." currentId: 0x43f4

"2023-02-16 11:34:39 267"

EW: 0x8b4

dealUDPReadReady: "funckwereretrtrtrtrtrtrtrtrtrt."

Student delete: "funckwereretrtrtrtrtrtrtrtrtrt." currentId: 0x8b4

通过分析发现,const Student &aa失去了意义,Student传递过程中与Student作为形参是一样的效果。

使用建议:避免这么操作。

  1. 用qt自带的QByteArray,QString 这种隐式共享方式进行参数传递,效率高,享元模式。

源代码下载链接:https://download.csdn.net/download/weixin_48975991/87454412

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九江在天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值