Как я могу создать «слабую» функцию и использовать ее с объектами? - PullRequest
0 голосов
/ 10 января 2019

Я пишу класс, который называется "MQTT_interface". Мне нужно использовать функцию «обратного вызова» в методе «Reconnect» этого класса. Я полагаю, что разработчик напишет функцию «обратный вызов» для себя, и если нет, то будет какая-то слабая функция с тем же именем («обратный вызов»), которая отправит ошибку на консоль.

Понятия не имею, возможно это или нет.

У меня есть эти файлы:

MQTT_interface.h

class MQTT_interface : public PubSubClient
{
    public:
    MQTT_interface(Client& c, String hostname, uint16_t port = 1883);
    void reconnect(void);

    private:
    uint8_t buf[UART_MAX_TRANSFER_SIZE];
};

MQTT_interface.cpp

void MQTT_interface::reconnect() {

    while (!connected()) {
  set_server(MQTT_auth_data.mqtt0_server, MQTT_auth_data.mqtt_port);
    if (connect(MQTT::Connect(MQTT_auth_data.mqtt_uid)
                           .set_auth(MQTT_auth_data.mqtt_uid, MQTT_auth_data.mqtt_pass))) {
      Serial.println("Connected to MQTT server");
      set_callback(callback);   //here my function must be used
        subscribe(topics.mqtt_subscribe_topic); // this is our receive filter. We able to receive only these topics
        subscribe(topics.mqtt_topic_1);

      } else {
        delay(timeout);
    }
  }
}

main.cpp

// Callback function
//  Receive data from MQTT and send it to serial
uint8_t buf[UART_MAX_TRANSFER_SIZE];
void callback(const MQTT::Publish& pub) {
// Copy the payload to a new message
  //MQTT::Publish newpub("outTopic", pub.payload(), pub.payload_len());
  //client.publish(newpub);
  String start_symbol = "";
  char end_symbol = '\n';
  String div_symbol = "&";
  //Serial.println(pub.topic());
  if (pub.has_stream()) {
    int read;
    while (read = pub.payload_stream()->read(buf, UART_MAX_TRANSFER_SIZE)) {
      Serial.write(buf, read);    
    }
    pub.payload_stream()->stop();
  }

  else{
    char symbol = 1;

    String t = pub.topic();
    String m = pub.payload_string();
    String message = start_symbol + t + div_symbol + m + end_symbol;
    int str_len ;
      str_len = message.length();
      Serial.print(message);
  }
}

1 Ответ

0 голосов
/ 10 января 2019

Позвольте пользователю дать вам функцию обратного вызова:

class MQTT_interface
{
public:
    using reconnect_callback = void(const MQTT::Publish&);

    static void reconnect_callback_default(const MQTT::Publish&) { /* your impl */ }
    void reconnect(reconnect_callback callback = reconnect_callback_default)
    {
        callback(/*...*/);
    }
};

Пример живого завершения :

#include <iostream>

struct example
{
    using reconnect_callback = void(int);
    static void reconnect_callback_default(int) { std::cout << "Error\n"; }
    void reconnect(reconnect_callback callback = reconnect_callback_default)
    {
        callback(42);
    }
};

int main()
{
    example e;
    e.reconnect();                                     // Error
    e.reconnect([](int n){ std::cout << n << '\n'; }); // 42
}

Это можно улучшить многими способами. Например, Макс Лангоф предлагает определить reconnect_callback как std::function, чтобы он мог быть функтором с состоянием.

...