Определите конструктор копирования, когда ключевое слово «this» используется внутри конструктора - PullRequest
0 голосов
/ 01 февраля 2019

У меня проблемы с определением конструктора копирования моего класса TextListener.Класс TextListener связывает метод callback с использованием ключевого слова this.Пожалуйста, ознакомьтесь с полным кодом ниже:

#include <iostream>
#include <ros/ros.h>
#include <std_msgs/String.h>

class TextListener {
 private:
  std::string _text;
  ros::Subscriber _subscriber;

 public:
  TextListener() {
    std::cout << "[" << this << "] deafult constructor called" << std::endl;
  }

  TextListener(const TextListener &other)
      : _subscriber(other._subscriber), _text(other._text) {
    std::cout << "[" << this << "] copy constructor called" << std::endl;
  }

  TextListener &operator=(const TextListener &other) {
    std::cout << "[" << this << "] copy assignment called" << std::endl;
    _subscriber = other._subscriber;
    _text = other._text;
    return *this;
  }

  TextListener(ros::NodeHandle &nh, const std::string &topicName) {
    std::cout << "[" << this << "] constructor called" << std::endl;
    _subscriber = nh.subscribe(topicName, 1, &TextListener::callback, this);
  }

  void callback(const std_msgs::String::ConstPtr &msg) { _text = msg->data; }

  std::string &getText() { return _text; }

  ~TextListener() {
    std::cout << "[" << this << "] destructor called" << std::endl;
  }
};

Чтобы протестировать вышеуказанный класс, я создал его экземпляр, который работает без каких-либо проблем.Однако, когда я создаю новый экземпляр и назначаю этот экземпляр новому экземпляру, новый экземпляр не работает.Ниже приведен фрагмент кода:

int main(int argc, char **argv) {
  ros::init(argc, argv, "tet_listener");

  ros::NodeHandle nh;
  std::string topicName = "chatter";
  TextListener listener(nh, topicName);
  TextListener copyListener = listener;

  ros::Rate loop_rate(1);
  while (ros::ok()) {
    ROS_INFO("I heard: [%s]", copyListener.getText().c_str());
    ros::spinOnce();
    loop_rate.sleep();
  }

  return 0;
}

Метод getText() не имеет значения.См. Ниже вывод:

[0x7ffc5698a2b0] constructor called
[0x7ffc5698a2d0] copy constructor called
[ INFO] [1549031938.250136695]: I heard: []
[ INFO] [1549031939.250183378]: I heard: []
[ INFO] [1549031940.250170333]: I heard: []
[ INFO] [1549031941.250176834]: I heard: []
^C[0x7ffc5698a2d0] destructor called
[0x7ffc5698a2b0] destructor called

Я предполагаю, что в конструкторе копирования что-то не хватает. Как определить конструктор копирования, когда ключевое слово "this" используется внутри конструктора?

1 Ответ

0 голосов
/ 01 февраля 2019

Вам нужны два Subscriber s, один, который уведомляет исходный объект TextListener, и один, который уведомляет копию TextListener

У вас действительно есть два подписчика, но так как один в копии TextListener являетсякопии оригинала, они оба обновляют исходный элемент _text TextListener.

Я не вижу лучшего способа, чем сохранить ссылку на NodeHandle в TextListener и заставить конструктор копирования повторно подписатьсяв NodeHandle вместо копирования подписки исходного объекта (которая вызывает обратный вызов исходного объекта).

...