2

我正在尝试使用重载的提取运算符简单地计算向量的元素。向量 contians Point,它只是一个包含两个双精度的结构。该向量是一个名为 Polygon 的类的私有成员,所以这是我的 Point.h

#ifndef POINT_H
#define POINT_H
#include <iostream>
#include <string>
#include <sstream>
struct Point
{
  double x;
  double y;
  //constructor
  Point()
  {
   x = 0.0;
   y = 0.0;
  }

friend std::istream& operator >>(std::istream& stream, Point &p)
    {
    stream >> std::ws;
    stream >> p.x;
    stream >> p.y;
    return stream;
    }
friend std::ostream& operator << (std::ostream& stream, Point &p)
{
stream << p.x <<  p.y;
return stream;
}    
};
#endif

我的多边形.h

#ifndef POLYGON_H
#define POLYGON_H
#include "Segment.h"
#include <vector>
class Polygon
{
    //insertion operator needs work
 friend std::istream & operator >> (std::istream &inStream, Polygon &vertStr);
 // extraction operator
 friend std::ostream & operator << (std::ostream &outStream, const Polygon &vertStr);

   public:
   //Constructor
    Polygon(const std::vector<Point> &theVerts);
    //Default Constructor
    Polygon();
    //Copy Constructor
    Polygon(const Polygon &polyCopy);
      //Accessor/Modifier methods
    inline std::vector<Point> getVector() const {return vertices;}
    //Return number of Vector elements
    inline int sizeOfVect() const {return vertices.size();}
    //add Point elements to vector
    inline void setVertices(const Point &theVerts){vertices.push_back (theVerts);}

 private:
std::vector<Point> vertices;
};

和多边形.cc

using namespace std;
 #include "Polygon.h"
// Constructor
Polygon::Polygon(const vector<Point> &theVerts)
    {
        vertices = theVerts;
    }
 //Default Constructor
Polygon::Polygon(){}

istream & operator >> (istream &inStream, Polygon::Polygon &vertStr)
 {
    inStream >> ws;
    inStream >> vertStr;
    return inStream;
 }

// extraction operator
 ostream & operator << (ostream &outStream, const Polygon::Polygon &vertStr)
{
    outStream << vertStr.vertices << endl;
    return outStream;
 }

我认为我的点插入/提取是正确的,我可以使用它插入和输出

我想我应该能够......

cout << myPoly[i] << endl;  

在我的司机?(循环)甚至......

cout << myPoly[0] << endl; 

没有循环?我已经尝试了各种

myPoly.at[i];
myPoly.vertices[i];

等等等等

还尝试了我的提取功能中的所有版本

outStream << vertStr.vertices[i] << endl;

在循环内等

当我刚刚创建一个...

vector<Point> myVect;

在我的驱动程序中,我可以...

cout << myVect.at(i) << endl;

没问题。

几天来试图找到答案,真的迷失了,而不是缺乏尝试!

请原谅我缺乏评论和格式,也缺少一些零碎的东西。

4

5 回答 5

5

把事情整理好。首先,术语:operator<<是一个插入操作符——它将项目插入到流中。operator>>是一个提取操作符——它从流中提取项目。

其次,您的插入运算符存在一些相当严重的问题。让我们从底部开始,point::operator<<. 现在你有:

friend std::ostream& operator << (std::ostream& stream, Point &p)
{
    stream << p.x <<  p.y;
    return stream;
} 

现在,让我们考虑一下当我们给它输入一些实数时会发生什么,比如 1.23 和 4.56。它会写出:

1.234.56

这显然是一个问题。没有办法,从查看数据本身,找出“x”结束和“y”开始的地方。我们需要对数据进行格式化,以便区分它们:

std::ostream &operator<<(std::ostream &stream, Point const &p) { 
    return stream << p.x << " " << p.y;
}

另请注意,由于我们不打算修改已传递的 Point,因此我已将其更改为const引用。

当/如果您尝试在文件中存储多个多边形时,您会再次遇到相同的问题 - 您有一个顶点流,但没有显示哪些顶点属于哪些多边形。例如,一个正方形后跟一个三角形可能如下所示:

0 0
1 0
1 1
0 1
1 1
2 2
0 2

一种明显的处理方法是在每个多边形前面加上它包含的顶点数,所以相同的数据看起来像这样:

4
0 0
1 0
1 1 
0 1
3
1 1
2 2 
0 2

然后我们可以在读回原始多边形时重新生成它们。为此,我们(显然)需要适当地编写我们的运算符:

std::ostream &operator<<(std::ostream &os, Polygon const &p) {
    std::vector<Point> v = p.getVector();
    os << v.size << "\n";

    // write each point out using operator<< for Point:
    std::copy(v.begin(), v.end(), std::ostream_iterator<Point>(os, "\n"));
    return os;
}

std::istream &operator>>(std::istream &is, Polygon &p) {     
    size_t size;
    is >> size;
    Point temp;
    for (int i=0; i<size; i++) {
        is >> temp;
        p.setVertices(temp);
    }
    return is;
}

看看这有多长,我想我现在就停在那里。

于 2010-04-06T15:38:27.203 回答
3

看看这个问题答案

这里的一般想法是,您确实必须遍历向量才能打印所有包含的对象,但您可以使用std::copy为您执行此操作。作为副本的目标,您只需使用一个std::ostream_iterator< Point >( std::cout )(在此处查找文档)。然后ostream_iterator使用您的重载operator <<forPoint打印各个点。这看起来是这样的:

std::copy( vertices.begin(), vertices.end(), std::ostream_iterator< Point >( std::cout ) );
于 2010-04-06T14:37:22.693 回答
2

您的输入和输出代码不应该是成员函数。将带有 istream 和 ostream 的部分移到类主体之外:

struct Point
{
   Point() : x(0.0), y(0.0) { }
   double x;
   double y;
};

inline std::istream& operator>> (std::istream& stream, Point& p)
{
    stream >> std::ws;
    stream >> p.x;
    stream >> p.y;
    return stream;
}

inline std::ostream& operator<< (std::ostream& stream, const Point& p)
{
  stream << p.x <<  p.y;
  return stream;
}

由于您的结构只有公共成员,因此不需要朋友。此外,当您编写输出函数时,您应该将对象作为 const 引用传递。

于 2010-04-06T14:39:50.967 回答
1

好的,我让循环像这样工作......

ostream & operator << (ostream &outStream, const Polygon::Polygon &vertStr) 
{ 
for (int i = 0; i < vertStr.sizeOfVect(); i++) 
{ 
outStream << vertStr.vertices.at(i) << endl; 
} 
return outStream; 
} 

那么就

cout << mainPoly << endl;

在司机

我确定我一遍又一遍地尝试过,不知道我做了什么不同,但是嘿,它有效,谢谢大家。

于 2010-04-07T06:26:50.243 回答
0

为了支持这个...

cout << myPoly[i] << endl;  

...您可以为您的 Polygon 类提供一个公共 operator[] ,它只需调用其顶点成员的 operator[] 。

Point const& Polygon::operator[](size_t n) const 
{
   return vertices[n];
}  

如果您选择以这种方式支持写入和读取,您将创建一个非常量重载,该重载返回一个非常量引用,但其他方面看起来相同。显然,在该版本中添加某种错误或不变检查可能是个好主意。

于 2010-04-06T15:49:44.490 回答