C++:获取随机符号作为输出,不确定原因[duplicate]

ruarlubt  于 2023-02-20  发布在  其他
关注(0)|答案(1)|浏览(133)
    • 此问题在此处已有答案**:

What is a dangling reference? [duplicate](1个答案)
What is a dangling pointer?(7个答案)
4天前关闭。
我一直在检查我的代码和摆弄,但我似乎不能弄清楚为什么我没有得到预期的输出,而是随机符号。
预期输出为:JoeUPS提醒领取您的包裹! 54.23
我明白了〈,但之后的任何东西都是胡言乱语。任何帮助都将不胜感激。

#include <cstddef>        // for std::size_t
#include <iostream>
#include <memory>
#include <ostream>
#include <string>
#include <utility>        // for std::move, std::forward
#include <vector>

class xml_node_base 
{
    public:
      virtual ~xml_node_base() = default;
      void output(std::ostream& os) const
      {
        do_output_open(os);
        do_output_body(os);
        do_output_close(os);
      }
    protected:
      virtual void do_output_open(std::ostream& os) const = 0; // abstract
      virtual void do_output_body(std::ostream&) const { } // not abstract
      virtual void do_output_close(std::ostream& os) const = 0; // abstract
};

using xml_node_base_t = std::shared_ptr<xml_node_base>;
using xml_node_bases_t = std::vector<xml_node_base_t>;

template <typename T, typename... Args>
inline xml_node_base_t make_xml_node(Args&&... args)
{
      return std::make_shared<T>(std::forward<Args>(args)...);
}   

class xml_node: virtual public xml_node_base
{
    private:
      std::string const& node_name;
    public:
      xml_node() = delete;
      xml_node(std::string const& name) : node_name(name)
      {
      };
    protected:
      void do_output_open(std::ostream& os) const override
      {
        os << "<" << node_name << ">";
      };
      void do_output_close(std::ostream& os) const override
      {
        os << "</" << node_name << ">";
      };
};

class xml_node_with_children: public xml_node

{
    private:
      xml_node_bases_t children_;
    public:
      xml_node_with_children() = delete;
      xml_node_with_children(std::string const& name) : xml_node(name)
      {
      };
      xml_node_with_children(std::string const& name, std::size_t reserve) : xml_node_with_children(name)
      {
        children_.reserve(reserve);
      };
      xml_node_with_children(std::string const& name, xml_node_bases_t children) : xml_node(name), children_(std::move(children))
      {
      };
    protected:
      auto& children() { return children_; };
      auto const& children() const { return children_; };
      void do_output_body(std::ostream& os) const
      {
        for (auto const& c : children_)
        {
            c -> output(os);
        }
      };
};

template <typename T>
class value_node : public xml_node
{
    private:
      T datum;
    protected:
      void do_output_body(std::ostream& os) const 
      {
        os << datum;
      }
    public:
      value_node(std::string const& name, T const& v) : xml_node(name), datum(v)
      {
      }
};

class note : public xml_node_with_children
{
    public:
      note() = delete;
      note(std::string const& to, std::string const& from, std::string const& subject, std::string const& message) : xml_node_with_children("note", 4)
      {
        children().push_back(make_xml_node<value_node<std::string>>("to",to));
        children().push_back(make_xml_node<value_node<std::string>>("from",from));
        children().push_back(make_xml_node<value_node<std::string>>("subject",subject));
        children().push_back(make_xml_node<value_node<std::string>>("message",message));
      }
};

class root : protected xml_node_with_children
{
    public:
      using xml_node_with_children::xml_node_with_children;
      using xml_node_with_children::output;
      using xml_node_with_children::children;
};

std::ostream& operator<<(std::ostream& os, root const& r)
{
    r.output(os);
    return os;
}

int main()
{
  root notes{"notes"};
  notes.children().push_back(
    make_xml_node<note>("Joe", "UPS", "Reminder", "Pick up your package!")
  );
  notes.children().push_back(
    make_xml_node<value_node<double>>("priority",54.23)
  );
  std::cout << notes << '\n';
}

我认为问题可能出在第90行的for循环上,因为我对-〉操作符不太熟悉。

bd1hkmkf

bd1hkmkf1#

std::string const& node_name;

      xml_node(std::string const& name) : node_name(name)

这个类成员是一个引用,构造函数从作为参数传递给构造函数的引用初始化它。
让我们一路回溯,看看构造函数的参数最初来自哪里,下面是一个例子:

children().push_back(make_xml_node<value_node<std::string>>("to",to));

该参数是一个文字字符串"to"
C++是非常有名的,它给了每个人每一个机会去搬起石头砸自己的脚,如果这是他们真正想做的话,所以:
1.构造一个临时的std::string对象。
1.对该对象的引用以参数的形式通过几个洋葱层的构造函数进行传递。
1.对此对象的引用保存在基类的成员中。
1.在所有构造函数完成并且此语句执行完毕之后,将销毁拥有此"to"的临时std::string对象。
1.类的示例现在在其node_name中具有对已销毁对象的引用。
1.对于所示代码中的所有其他对象,都是这样构造的。
1.你刚搬起石头砸了自己的脚。

相关问题