基本概念
QPointer提供了模板类,这个包含指针主要是针对于QObject。
当对象被销毁的时候会被自动设置为0,解决了指针悬挂问题。这里QPointer中的T必须是QObject的子类,也就是identity type的Qt类。
(相关资料图)
QPinter的删除
对象树不能解决指针悬挂的问题:
1. QPointer为QObject提供了保护指针;
2. 当引用的对象被销毁时,QPointer会被设置为0;
3. 能适应任意的指针(保护指针自动转换为指针类型);
官方例子:
// ExampleObject is just QObject subclassQPointerobject(new ExampleQObject);delete object;if (object)qDebug() << ”Dangling pointer";elseqDebug() << "No dangling pointer";
这里本人做了一个涉及QPointer的实例
程序运行截图如下:
生产者生产数据,这个数据是QObject。然后有4-5个消费者去消费,在拿数据的时候加个锁,避免并发拿数据时出现问题:
QObject* ProjectData::getItem(){mutex.lock();if(m_objList.size() == 0){mutex.unlock();return nullptr;}QObject *ret = m_objList[0];m_objList.removeFirst();mutex.unlock();return ret;}
关键代码如下:
消费者线程:
#include "WorkerThread.h"#include "ProjectData.h"#include #include WorkerThread::WorkerThread(){stopFlag = false;qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));}void WorkerThread::setProjectData(ProjectData *project){m_project = project;}void WorkerThread::run(){while(true){if(stopFlag){QThread::sleep(1);break;}QPointerptr = m_project->getItem();if(!ptr){QThread::sleep(1);continue;}//开始处理数据int disposeTime = qrand() % 5;qDebug() << "线程:" << QThread::currentThread() << "处理" << ptr << " 需要" << disposeTime << "S";QThread::sleep(disposeTime);delete ptr;//qDebug() << "ptr" << ptr;}}
调用及退出:
#include #include #include #include #include "WorkerThread.h"#include "ProjectData.h"int main(int argc, char *argv[]){QCoreApplication a(argc, argv);ProjectData *p = new ProjectData;//设置消费者线程WorkerThread *p1 = new WorkerThread;WorkerThread *p2 = new WorkerThread;WorkerThread *p3 = new WorkerThread;WorkerThread *p4 = new WorkerThread;WorkerThread *p5 = new WorkerThread;p1->setProjectData(p);p2->setProjectData(p);p3->setProjectData(p);p4->setProjectData(p);p5->setProjectData(p);p1->start();p2->start();p3->start();p4->start();p5->start();//设置生产者生产者QTimer timer;QObject::connect(&timer, &QTimer::timeout, [=](){QObject *test = new QObject;test->setObjectName("新数据ABC");p->addItem(test);qDebug() << "当前剩余资源:" << p->getSize();});timer.start(300);QTimer::singleShot(1000 * 20, [=]{p1->stopFlag = true;p2->stopFlag = true;p3->stopFlag = true;p4->stopFlag = true;p5->stopFlag = true;QEventLoop loop;QTimer::singleShot(1000 * 5, &loop, SLOT(quit()));loop.exec();delete p;qDebug() << "退出";qApp->quit();});return a.e
【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】
点击这里:
关键词: