用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类只实例化了一次,并在槽函数作用域运行结束后,这块内存释放。
优点:相当于在指针加了一个外壳,传递的是智能指针,引用计数加一,不会再进行复制构造函数,大大降低传递过程中系统开销。
注意事项:不能强制以栈对象取地址的方式,初始化智能指针,这样会导致内存不安全。
用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作为形参是一样的效果。
使用建议:避免这么操作。
用qt自带的QByteArray,QString 这种隐式共享方式进行参数传递,效率高,享元模式。
源代码下载链接:https://download.csdn.net/download/weixin_48975991/87454412