【问题标题】:Problems regarding Overloading the input operator >> for reading text file关于重载输入操作符>>读取文本文件的问题
【发布时间】:2013-11-10 14:43:54
【问题描述】:

我有一个Point2D 类,我正在尝试重载输入运算符 >>

class Point2D
{
 public:
           Point2D(int,int);
           int getX();
           int getY();

           void setX(int);
           void setY(int);

           double getScalarValue();

          bool operator < ( const Point2D& x2) const
          {
            return x < x2.x;
          }

              friend istream& operator >> (istream&,Point2D);


 protected:

             int x;
             int y;
             double distFrOrigin;
             void setDistFrOrigin();


};

在我的主要功能之外

    #include <iostream>
    #include <fstream>
    #include "Line2D.h"
    #include "MyTemplates.h"
    #include <string>
    #include <set>

    using namespace std;

    istream operator >> (istream& is , Point2D p2d)
    {
        string p;
        getline(is,p,'\n');
       int position = p.find(", ");

        string k = p.substr(0,position);

       if ( k == "Point2D")
       {
         string x = p.substr(10,1);
         int x_coordinate = atoi(x.c_str()); // atoi(x.c_str()) convert string x to int
         p2d.setX(x_coordinate);

       }

       return is;
    }

在我的 int main() 中

    int main()
{

   fstream afile;
   string p;
   afile.open("Messy.txt",ios::in);

   if (!afile)
   {
     cout<<"File could not be opened for reading";
     exit(-1);
   }

   Point2D abc;

   afile>>abc;

   set<Point2D> P2D;
   P2D.insert(abc);

   set<Point2D>::iterator p2 = P2D.begin();

   while ( p2 != P2D.end() )
   { 
     cout<<p2->getX();
     p2++;
   }

}

我不明白为什么会出错:

c++ 禁止声明没有类型的 istream

我已经包含了 iostream , fstream ,使用命名空间 std ,我不知道是什么问题

【问题讨论】:

  • 您需要通过引用返回std::istream(它不能被复制,即按值返回不起作用)并通过引用传递您的参数(否则您将修改本地对象)。在你的声明中(在课堂上)你应该使用std::istream而不是istream
  • 对不起,我是 c++ 新手,什么意思?
  • istreamstd 命名空间中,所以你需要friend std::istream&amp; operator &gt;&gt; (std::istream&amp;, Point2D&amp;); 不要使用using namespace std;,反正这很糟糕,并且会导致你的代码有些混乱。跨度>
  • 当我已经有“使用命名空间标准”时,我需要包含什么 std::
  • 您可能不在using namespace std 需要它的地方(为了安全起见,不要在任何地方这样做),而且您可能包含也可能不包含必需的标题。

标签: c++ overloading istream


【解决方案1】:

您的代码中有几个问题。

  1. 这是您的错误消息的原因。你不会在Point2D.h/Line2D.h#include &lt;iostream&gt;

    正如其他人已经建议的那样,使用std::istream 而不仅仅是istream

  2. 正确的operator&gt;&gt;()应该是

    std::istream &operator>>(std::istream &is, Point2D &p2d);
    

    注意std::istream&amp; Point2D&amp;Point2D&amp; 很重要,否则你修改一个本地副本并且给定的参数保持不变。

  3. 您的输入运算符很脆弱。它容易受到或多或少的空格的影响。您还允许 x_coordinate 恰好有 一个 位。此外,您在Point2D, 之外跳过一个字符。更好的方法可能是仅用空格分隔部分,并让 iostream 库处理解析。例如。

    Point2D 15 28
    

    可以被

    读取
    string tag;
    is >> tag;
    if (tag == "Point2D")
        is >> p2d.x >> p2d.y;
    
    return is,
    

【讨论】:

  • 只是想知道为什么在我的 Point2D 头文件中重复 #include 时我已经将它包含在我的主文件中
  • 你当然不需要。但正如您所看到的,依赖其他地方的包含 and using namespace 会给您错误消息。如果您坚持在Line2D 之前包含iostream,您还必须说使用命名空间之前 包括Line2D。因此,最好在相关的头文件中而不是在其他地方做必要的先决条件。因此建议:在Line2D 中包含并使用std::istream 而不是using namespace
【解决方案2】:

突然出现的事情(正如 Dietmar Kühl 提到的)是您没有返回 istream 的引用。尝试更改此方法标头

istream operator >> (istream& is , Point2D p2d)

到这里:

istream& operator >> (istream& is , Point2D p2d)

根据经验,返回对未创建复制构造函数的对象的引用通常是个好主意。返回引用意味着您正在返回对象所在的地址。要正确按值返回,需要对所返回的对象进行复制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-19
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多