在构造函数中使用关键字 "this" 时定义复制构造函数
Define copy constructor when keyword "this" is used inside constructor
我在定义 class TextListener
的复制构造函数时遇到困难。 class TextListener
使用 this
关键字绑定方法 callback
。完整代码请见下方:
#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;
}
};
为了测试上面的 class,我创建了它的一个实例,它没有任何问题。但是,当我创建一个新实例并将该实例分配给新实例时,新实例不起作用。下面是代码片段:
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"时如何定义复制构造函数?
您需要两个 Subscriber
,一个通知原始 TextListener 对象,一个通知副本 TextListener
您实际上有两个订阅者,但由于副本 TextListener 中的订阅者是原始订阅者的副本,因此它们都更新了原始 TextListener 的 _text 成员。
我看不到比在 TextListener 中保留对 NodeHandle 的引用,并让复制构造函数重新订阅 NodeHandle 而不是复制原始对象的订阅(调用原始对象的回调)更好的方法).
我在定义 class TextListener
的复制构造函数时遇到困难。 class TextListener
使用 this
关键字绑定方法 callback
。完整代码请见下方:
#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;
}
};
为了测试上面的 class,我创建了它的一个实例,它没有任何问题。但是,当我创建一个新实例并将该实例分配给新实例时,新实例不起作用。下面是代码片段:
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"时如何定义复制构造函数?
您需要两个 Subscriber
,一个通知原始 TextListener 对象,一个通知副本 TextListener
您实际上有两个订阅者,但由于副本 TextListener 中的订阅者是原始订阅者的副本,因此它们都更新了原始 TextListener 的 _text 成员。
我看不到比在 TextListener 中保留对 NodeHandle 的引用,并让复制构造函数重新订阅 NodeHandle 而不是复制原始对象的订阅(调用原始对象的回调)更好的方法).