【问题标题】:Use of std::ostream for Printing Vectors使用 std::ostream 打印向量
【发布时间】:2015-12-15 01:31:21
【问题描述】:

我对 C++ 很陌生,我正在尝试打印一个机构向量,这是我创建的一种对象。对象的创建和我的程序的其余部分运行得很好,但是当我尝试打印出向量时,“

void PrintVector(const vector<Institution> &institutions)
{
    for (int x = 0; x < institutions.size; x++)
    {
        cout << institutions.at(x) << endl;
    }
}

我试图研究 std::ostream 是什么或它的作用,但由于我对 C++(或一般编程)知之甚少,我无法理解任何解释的网站它。为什么通常的“cout

感谢您的帮助。

【问题讨论】:

  • 你为你的Institution班级写了operator &lt;&lt;吗?
  • 既然您知道x 的值是向量中的有效索引,那么用institutions.at(X) 再次检查它们是没有意义的。只需使用institutions[x]。更好的是,阅读迭代器。

标签: c++ vector ostream


【解决方案1】:

您可能希望为您的班级机构重载 ostream 运算符 (https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx

ostream& operator<<(ostream& os, const Institution& inst)
{
    os << inst.foo; /* some member variable */;
    return os;
}

【讨论】:

  • @LiliaO.是的,你会把所有你想打印的成员都放进去
  • @Tas 如果我想打印多个成员,我会这样做吗? os &lt;&lt; inst.x &lt;&lt; inst.y &lt;&lt; inst.z;
  • @LiliaO。是的,这是正确的,您可以根据需要对其进行格式化(中间有换行符等,甚至可以通过“机构名称为”
  • @LiliaO。塔斯是正确的。您可以使用流运算符进行各种精美的打印。 os
  • @LiliaO。您需要将 operator &lt;&lt; 设为 friendInstitution 或提供 public getter。
【解决方案2】:

问题是 C++ ostreamcout 是)没有任何方法可以打印出 Institution 对象。您将不得不重载 Institution 中的 operator&lt;&lt; 函数,如另一个答案 (https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx?f=255&MSPPError=-2147217396) 中发布的链接中所述,才能使其正常工作。

【讨论】:

    【解决方案3】:

    您必须为您的班级提供operator &lt;&lt;

    std::ostream& operator << (std::ostream& os, const Institution& institution)
    {
        os << institution.getValue();
        // ...
        return os;
    }
    

    【讨论】:

      【解决方案4】:

      operator&lt;&lt; 被重载以允许输出像intdouble 这样的内置类型。但是您需要通过再次重载来告诉编译器如何输出您的类Institution

      std::ostream& operator<<(std::ostream& os, const Institution& inst) {
          os << inst.name(); // or something
          return os;
      }
      

      【讨论】:

      • 男人竞争很激烈T.T
      【解决方案5】:

      您显示的代码至少有两个问题。

      1)

      for (int x = 0; x < institutions.size; x++)
      

      std::vector::size() 是一个类方法,一个函数。它不是班级成员。这应该是:

      for (int x = 0; x < institutions.size(); x++)
      

      2)

      cout << institutions.at(x) << endl;
      

      不幸的是,std::ostream 对您的 Institution 课程一无所知。您将需要实现一个类方法,例如display(),它将组装类内容的可打印表示,并将其写入输出流。因此,例如,如果该类包含两个std::strings,分别称为nameaddress

      class Institution {
      
      // ...
      
      public:
      
            void display(std::ostream &o)
            {
                 o << name << std::endl << address << std::endl;
            }
      // ...
      };
      

      ... 或者,您希望以任何格式样式显示您的类实例。那么:

      for (int x = 0; x < institutions.size(); x++)
           institutions.at(x).display(std::cout);
      

      3)

      嗯,这是您的代码的一个额外问题。它实际上是用几十年前过时的过时 C++ 方言编写的。无论你用什么教科书来学习 C++,你都需要放弃它,选择一本本世纪编写的教科书,它将教你现代 C++。在现代 C++ 中,这变得更具可读性:

      for (const auto &institution:institutions)
           institution.display(std::cout);
      

      【讨论】:

        【解决方案6】:

        这里的答案都是正确的。我将对显示问题提供稍微不同的答案,因为这是一个反复出现的问题。你可以做的是定义一个抽象类,我们称之为IDisplay,它声明一个纯虚函数std::ostream&amp; display(std::ostream&amp;) const,并声明operator&lt;&lt;为友元。然后,您希望显示的每个类都必须继承自 IDisplay 并因此实现 display 成员函数。这种方法重用代码并且非常优雅。示例如下:

        #include <iostream>
        
        class IDisplay
        {
        private:
            /**
            * \brief Must be overridden by all derived classes
            *
            * The actual stream extraction processing is performed by the overriden
            * member function in the derived class. This function is automatically
            * invoked by friend inline std::ostream& operator<<(std::ostream& os,
            * const IDisplay& rhs).
            */
            virtual std::ostream& display(std::ostream& os) const = 0;
        
        public:
            /**
            * \brief Default virtual destructor
            */
            virtual ~IDisplay() = default;
        
            /**
            * \brief Overloads the extraction operator
            *
            * Delegates the work to the virtual function IDisplay::display()
            */
            friend inline
            std::ostream& operator<<(std::ostream& os, const IDisplay& rhs)
            {
                return rhs.display(os);
            }
        }; /* class IDisplay */
        
        class Foo: public IDisplay
        {
        public:
            std::ostream& display(std::ostream& os) const override 
            {
                return os << "Foo";
            }
        };
        
        class Bar: public IDisplay
        {
        public:
            std::ostream& display(std::ostream& os) const override 
            {
                return os << "Bar";
            }
        };
        
        int main() 
        {
            Foo foo;
            Bar bar;
            std::cout << foo << " " << bar;    
        }
        

        Live on Coliru

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-03-01
          • 2015-03-02
          • 1970-01-01
          • 2021-05-28
          • 1970-01-01
          • 2019-08-01
          • 2011-12-10
          相关资源
          最近更新 更多