QТ - класс для подключения к протоколу MQTT брокер с QMqttClient


Задачи:

Класс для подключения к протоколу MQTT брокера с помощью QMqttClient и получать уведомления на connect и disconnect.

Контекст:

Я пытаюсь написать современный C++ (стандарт 2011 года) код - с помощью смарт-указатели. Я создал только небольшие проекты по изучению c++. Я не очень уверен, если я правильно используя эти указатели.

Реализация:

Реализация в client.h и client.cpp заголовок файла. Первый фрагмент кода-это client.h один.

#ifndef CLIENT_H
#define CLIENT_H

#include <QString>
#include <QObject>
#include <QtMqtt/QtMqtt>
#include <memory>
#include <iostream>

struct MqttConfig {
    MqttConfig() {
        hostname = "localhost";
        port = 1883;
    }

    QString hostname;
    quint16 port;
};

struct SubscriptionConfig
{
    SubscriptionConfig() = delete;
    SubscriptionConfig(QString t, quint16 q) :
        topic(t), qos(q)
    {}

    QString topic;
    quint16 qos; // quality of service
};

class Client : public QObject
{
    Q_OBJECT

private:
    std::unique_ptr<QMqttClient> mqtt;
    std::unique_ptr<MqttConfig> c;

public:
    Client();
    void connectToSignals();
    void configureClient(std::unique_ptr<MqttConfig>&);
    void connect();

public slots:
    void onConnected()
    { std::cout << "Connected to mqtt broker " << std::endl; }
    void onDisconnected()
    { std::cout << "Disconnected from mqtt broker" << std::endl; }
};

#endif // CLIENT_H

Я нарушая DRY принцип (не повторяйся) в методе connectToSignals ? И как я могу избежать этого?

#include "client.h"

Client::Client()
{
    mqtt = std::make_unique<QMqttClient>();
    c = std::make_unique<MqttConfig>();
    configureClient(c);
    connectToSignals();
    connect();
}

void Client::connectToSignals()
{
    QObject::connect(Client::mqtt.get(), &QMqttClient::connected, this,
                     &Client::onConnected);
    QObject::connect(Client::mqtt.get(), &QMqttClient::disconnected, this,
                     &Client::onDisconnected);
}

void Client::configureClient(std::unique_ptr<MqttConfig>& c)
{
    mqtt->setHostname(c->hostname);
    mqtt->setPort(c->port);
}

void Client::connect()
{
    mqtt->connectToHost();
}


496
2
задан 7 апреля 2018 в 05:04 Источник Поделиться
Комментарии
1 ответ

Qт-Несс

Мой Qt-это немного ржавый, но ты, наверное, не делал правильно. Первый QObject иметь собственное управление памятью, обычно каждый QObject конструктор принимает parentэтот родитель принимает право собственности на созданный объект. Как setParent() функция всегда доступна, мешая управления памятью через std::unique_ptr или std::shared_ptr это обычно не является хорошей идеей.

Кроме того, вы не содержащий QMQTTClient за то, что выглядит как просто конфигурации причин, то действительно, кажется, не быть никакой необходимости, чтобы обернуть его в другой слой, вы можете просто заменить свой клиент с QMQTTClient и подключиться к нему. Если вы хотите обернуть конфигурации, свободной функции будут делать с гораздо меньшими затратами.

Стек против кучи

Как QMQTTClient и MQTTConfig может также быть стек выделяется, что делает все проще. Прохождение MQTTConfig по ссылке будет работать достаточно хорошо.

MQTTConfig

Конструктор должны использовать списки инициализации, а не в теле функции для инициализации переменной-члена.

MqttConfig() : hostname("localhost"), port(1883) {}

Я бы, наверное, предпочел значения по умолчанию для этого

MqttConfig(QString h = "localhost", qint16 p = 1883  ) : hostname(h), port(p) {}

SubscriptionConfig

Конструктор по умолчанию не должны быть удалены, при определении пользовательского конструктора

2
ответ дан 11 апреля 2018 в 02:04 Источник Поделиться