在构造函数之外延长 QT 对象的生命周期

Posted

技术标签:

【中文标题】在构造函数之外延长 QT 对象的生命周期【英文标题】:to extend the lifetime of a QT object outside of the constructor 【发布时间】:2019-09-21 06:02:03 【问题描述】:

这是给我的问题

    创建一个名为 datamanager 的项目,它的基类应该是 QWidget 添加一个从 QObject 继承的名为 controller 的新类 和 2 个插槽,称为 sensordatarecived 和 startdatacollection 在控制器中 添加另一个继承自 QObject 的名为 commonreader 的类 在 commonreader 类中定义 2 个分别称为 readingStarted() 和 readCompleted() 的信号 添加一个名为 sendData() 的槽 在 commonreader 类中声明一个名为 monitor() 的虚函数 新增 5 个继承自 commonreader 类的新传感器类 在所有上述类中重新实现了通用的 Monitor() 函数 使用 QTimer 对象实现从定义的 5 个类中的每一个的 monitor() 函数发出 readingStarted() 实现 sendData() 槽 在发送数据槽() 中发出名为 readcompleted 的信号 在控制器的构造函数中创建上述每个传感器类的对象 从 startDataCollection() 调用方法传感器对象的 monitor() 函数 将每个对象的 readComplete() 信号连接到控制器的 sensordatarecieved()。

这些是我为一个项目必须遵循的步骤。我被困在第 14 步,我需要帮助。

//controller.h
class controler : public QObject

    Q_OBJECT
public:
    explicit controler(QObject *parent = nullptr);

signals:

public slots:
    void sensorDataRecived();
    void startDataCollection();

;

//controller.cpp

#include "controler.h"
#include <QDebug>
#include "heart_1_sensor.h"
#include "eye_2_sensor.h"
#include "brain_3_sensor.h"
#include "ear_5_sensor.h"
#include "head_4_sensor.h"
#include "commonreaderclass.h"

controler::controler(QObject *parent) : QObject(parent)

    commonReaderClass *h1=new heart_1_Sensor;
    commonReaderClass *e2=new eye_2_Sensor;
    commonReaderClass *b3=new brain_3_sensor;
    commonReaderClass *e5=new ear_5_sensor;
    commonReaderClass *h4=new head_4_sensor;





void controler::sensorDataRecived()

    qDebug()<<Q_FUNC_INFO<<endl;



void controler::startDataCollection()


//commonreaderclass.h

#ifndef COMMONREADERCLASS_H
#define COMMONREADERCLASS_H

#include <QObject>

class commonReaderClass : public QObject

    Q_OBJECT
public:
    explicit commonReaderClass(QObject *parent = nullptr);
    virtual void monitor();

signals:
    void readingStarted();
    void readCompleted();

public slots:
    void sendData();
;

#endif // COMMONREADERCLASS_H

//commonreaderclass.cpp
#include "commonreaderclass.h"
#include <QDebug>
#include <QTimer>

commonReaderClass::commonReaderClass(QObject *parent) : QObject(parent)




void commonReaderClass::sendData()

    qDebug()<<"sending data has started"<<endl;
    emit readCompleted();


//sensor1.h
#ifndef HEART_1_SENSOR_H
#define HEART_1_SENSOR_H
#include "commonreaderclass.h"


class heart_1_Sensor:public commonReaderClass

public:
    heart_1_Sensor();
    virtual void monitor();
;

#endif // HEART_1_SENSOR_H
//sensor 1.cpp
#include "heart_1_sensor.h"
#include <QDebug>
#include <QTimer>

heart_1_Sensor::heart_1_Sensor()




void heart_1_Sensor::monitor()

    qDebug()<<"monitoring the heart"<<endl;
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(sendData()));
        timer->start(2000);
        emit readingStarted();


//and another 4 sensors of the same implementation

【问题讨论】:

看起来你需要阅读你最喜欢的 C++ 书籍中的成员变量。 【参考方案1】:

我同意@molbdnilo 的观点,即您应该使 h1、e2、... 成为类的成员,而不是构造函数中的局部变量。但是在这种情况下,还有一个考虑因素:QObject 实例的生命周期是特殊的,因为它们之间的父/子关系,所以当父级被销毁时,子级可以自动销毁。我推荐你this book(也有纸质版)。特别是chapter 2 关于类和chapter 8 关于QObject 和其他重要的Qt 类。这本书是一门课程,你应该从头到尾跟着它,同时还要阅读其他书籍。

控制器.h

class Controller : public QObject

    Q_OBJECT
public:
    explicit Controller(QObject *parent = nullptr);
    ~Controller(); // the destructor
    // ... more public members
signals:
    // ... 
public slots:
    // ... 
private:
    commonReaderClass *m_h1;
    commonReaderClass *m_e2;
    // ...
;

我已将变量 h1 重命名为 m_h1 并将 e2 重命名为 m_e2,遵循 a common convention 的成员变量名称,并且以大写开头的 Controller 类名称是另一种常见的命名约定。

controller.cpp(经典的 C++ 方式)

Controller::Controller(QObject *parent) : QObject(parent)

    m_h1 = new heart_1_Sensor;
    m_e2 = new eye_2_Sensor;
    // ...


Controller::~Controller()

    delete m_h1;
    delete m_e2;
    // ...

controller.cpp(Qt 方式)

Controller::Controller(QObject *parent) : QObject(parent)

    m_h1 = new heart_1_Sensor(this);
    m_e2 = new eye_2_Sensor(this);
    // ...


Controller::~Controller()
 

在编写基于 Qt 的程序时,通常首选 controller.cpp 的第二个版本。您应该记住,在 C++ 中,每个使用 new 操作初始化的指针都应该有一个对应的 delete 操作。 C++ 中没有自动“垃圾回收”,但QObject 提供了一种相当舒适的机制来自动删除子对象,因此第二个版本中的析构函数可能为空,也可以完全省略。

【讨论】:

非常感谢!我得到了它的工作,感谢您推荐这本书 qt 将通过这本书更好地理解。 @佩德罗

以上是关于在构造函数之外延长 QT 对象的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 - 构造函数调用后的生命周期事件

Flutter:在构造函数中调用 setState():_SharesListState#6c96a(生命周期状态:已创建,无小部件,未安装)

unity中的构造函数

面向对象(构造及析构函数)

基于类的 vue 组件属性定义:构造函数 vs.getter/setter vs.mounted 生命周期

Servlet生命周期 和 继承关系