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

这是给我的问题

  1. 创建一个名为 datamanager 的项目,它的基类应该是 QWidget
  2. 添加一个从 QObject 继承的名为 controller 的新类
  3. 和 2 个插槽,称为 sensordatarecived 和 startdatacollection 在控制器中
  4. 添加另一个继承自 QObject 的名为 commonreader 的类
  5. 在 commonreader 类中定义 2 个分别称为 readingStarted() 和 readCompleted() 的信号
  6. 添加一个名为 sendData() 的槽
  7. 在 commonreader 类中声明一个名为 monitor() 的虚函数
  8. 新增 5 个继承自 commonreader 类的新传感器类
  9. 在所有上述类中重新实现了通用的 Monitor() 函数
  10. 使用 QTimer 对象实现从定义的 5 个类中的每一个的 monitor() 函数发出 readingStarted()
  11. 实现 sendData() 槽
  12. 在发送数据槽() 中发出名为 readcompleted 的信号
  13. 在控制器的构造函数中创建上述每个传感器类的对象
  14. 从 startDataCollection() 调用方法传感器对象的 monitor() 函数
  15. 将每个对象的 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++ 书籍中的成员变量。

标签: c++ qt c++11 qt5


【解决方案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 将通过这本书更好地理解。 @佩德罗
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 2023-02-15
  • 2011-03-16
  • 1970-01-01
  • 2013-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多