以延长构造函数外部 QT 对象的生存期

to extend the lifetime of a QT object outside of the constructor

本文关键字:对象 生存期 QT 外部 构造函数      更新时间:2023-10-16

这是给我的问题

  1. 创建一个名为datamanager的项目,其基类应该是QWidget
  2. 添加一个名为控制器的新类继承自 QObject
  3. 控制器中还有 2 个称为传感器接收和启动数据收集的插槽
  4. 添加另一个从 QObject 继承的名为 commonreader 类的类
  5. 在 commonreader 类中定义 2 个信号,分别称为 readingStarted(( 和 readComplete((
  6. 添加一个名为 sendData(( 的插槽
  7. 在 commonreader 类中声明一个名为 monitor(( 的虚函数
  8. 添加 5 个继承自 commonreader 类的新传感器类
  9. 在上述所有类中重新实现通用的 Monitor(( 函数
  10. 使用 QTimer 对象实现从定义的 5 个类中每个类的 monitor(( 函数发出 readingStarted((
  11. 实现 sendData(( 插槽
  12. 在发送数据槽((内发出名为"读取完成"的信号
  13. 在控制器的构造函数中创建上述每个传感器类的对象
  14. 调用 monitor(( 方法传感器对象的函数从开始数据收集((
  15. 将每个对象的 readComplete(( 信号连接到控制器的传感器数据接收((。

这些是我必须遵循的项目步骤。我被困在第 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

我同意@molbdnilo的观点,你应该制作 h1、e2、...类的成员,而不是构造函数中的局部变量。但在这种情况下,还有一个注意事项:QObject实例的生存期是特殊的,因为它们之间的父/子关系,因此可以在父实例被销毁时自动销毁子实例。我向你推荐这本书(也有纸质印刷版(。特别是关于类的第2章和第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,并且以大写开头的控制器类名称是另一种常见的命名约定。

控制器.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;
// ...
}

控制器.cpp(Qt方式(

Controller::Controller(QObject *parent) : QObject(parent)
{
m_h1 = new heart_1_Sensor(this);
m_e2 = new eye_2_Sensor(this);
// ...
}
Controller::~Controller()
{ }

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