【问题标题】:boost::property_tree put usage C++boost::property_tree put 用法 C++
【发布时间】:2019-02-10 04:32:11
【问题描述】:

我在类成员函数中执行ptree.put()。

class Writer{
private:
    boost::property_tree::ptree ptree_;
public:
    Writer(){}
    void setData1(string path, string data){
        ptree_.put(path, data);
    }
    void setData2(string path, string data){
        ptree_.put(path, data);
    }
    void printPtree(){
        boost::property_tree::write_json(std::cout, ptree_);
    }
};

我正在创建类的一个实例,setData1() 被代码中的回调函数调用(多个 ROS 订阅者回调)。

当我在main() 中调用setData2() 时,它按预期工作。但是当回调调用类似的setData1()时,ptree_最后是空的。当我两者都做时,ptree_ 只有setData2() 写入的数据。

当我在每次调用时在setData1() 中打印ptree_ 时,可以在ptree_ 中看到该调用的数据,但看不到之前调用中写入的数据。调用printPtree() 时,没有使用setData1() 写入的数据。只有使用setData1() 写入的数据保持不变。

我写了两个相同的setData 方法,以便我可以清楚地解释我的问题。我在这里做错了什么?


编辑:这是我的代码的最小版本。这是一个 ROS 节点。

class Writer{
private:
    pt::ptree ptree_;

public:
    Writer(){}

    void setData(string branch, string data){
        ptree_.put(branch, data);
        // gets ptree content at each call
        // pt::write_json(std::cout, ptree_);
    }
    ~Writer(){
        pt::write_json(std::cout, ptree_);
    }
};

class SubscriberHandler{
private:
    ros::Subscriber sub_;
    Writer writer_;
public:
    SubscriberHandler(string topic_name_, Writer & writer) : writer_(writer){
        ros::NodeHandle n;
        sub_ = n.subscribe(topic_name_, 10, &SubscriberHandler::callback, this);
    }
    // this is the ROS callback function
    void callback(const topic_tools::ShapeShifter::ConstPtr& msg){
        --- CODE TO GET DATA FROM msg---
        writer_.setData(path, value);
    }
};

class SomeClass{
    Writer writer;
public:
    SomeClass(){
        writer.setData("Velocity.x", "50");
        writer.setData("Velocity.y", "10.5");
        // I have to create these objects inside a class
        SubscriberHandler sh("my_topic", writer);
    }
};

int main(){
    ros::init("node_name");

    SomeClass sc;

    ros::spin()
    return 0;
}

这是我最后的ptree_

{
    "Velocity": {
        "x": "50",
        "y": "10.5"
    }
}

但如果我在每次通话时打印ptree_,它就会包含在该特定通话+以上发送的数据。由于这似乎是与我的 C++ 知识有关的问题,因此我在此处发布了问题而不是 ROS 答案。

【问题讨论】:

  • 您首先描述了setData1 和setData2 如何相似 并且显然具有不同的行为,但随后您表明它们是相同。这并没有让事情变得更清楚。请听从@Someprogrammerdude 的建议。
  • 猜测您正在将Writer 对象复制到某处并修改副本而不是原始对象。需要minimal reproducible example 才能更有帮助。
  • 我添加了代码的最小版本。 @AlanBirtles 是的,这种行为暗示了类似的事情,但我没有看到在我的代码中发生这种情况的原因
  • 小心:sh 立即超出范围,因此您不能保证在对象仍然存在时调用回调。到那时它可能已经被摧毁了。

标签: c++ boost ros boost-propertytree ptree


【解决方案1】:

您有两个 Writer 实例:

  • 在main 中创建的SomeClass 实例的writer 成员。其中的属性树有"Velocity.x" 和"Velocity.y" 集。
  • SubscriberHandler 实例的writer_ 成员在SomeClass 构造函数中创建。这是第一个 Writer 实例的副本(因为 SubscriberHandler 构造函数复制了它)。其中的属性树有"Velocity.x"、"Velocity.y" 和path 集。

【讨论】:

  • 我现在明白了。我问了这么愚蠢的问题。谢谢@Sander
  • @TeshanShanukaJ :最简单的解决方案是让writer_ 成为参考。这意味着你必须担心对象的生命周期,所以像 std::shared_ptr 这样的东西可能会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 2011-06-27
  • 2012-09-14
  • 2015-10-02
相关资源
最近更新 更多