带向量的重载流插入运算符

发布于 2024-08-28 04:19:19 字数 2160 浏览 5 评论 0原文

我正在尝试为一个唯一成员是向量的类编写一个重载的流插入运算符。它是一个由Point组成的向量,它是一个包含两个doublestruct。 我想我想要的是将用户输入(一堆double)插入到一个流中,然后将其发送到修饰符方法。我正在处理其他流插入示例,例如:

std::ostream& operator<< (std::ostream& o, Fred const& fred)
 {
   return o << fred.i_;
 }

但是当我尝试类似的操作时:

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

我收到错误“与 operator >> 等不匹配”等。如果我省略 .vertices,它会编译,但我认为这是不对的。 (顺便说一句,vertices 是我的向量 的名称。)即使它是正确的,我实际上也不知道要使用什么语法我的程序使用它,而且我也不能 100% 确定我的修饰符方法需要是什么样子。

这是我的 Polygon 类:

//header

#ifndef POLYGON_H
#define POLYGON_H
#include "Segment.h"
#include <vector>
class Polygon
{
 friend std::istream & operator >> (std::istream &inStream, Polygon &vertStr);
 public:
   //Constructor
    Polygon(const 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 (int) vertices.capacity();}
    //add Point elements to vector
    inline void setVertices(const Point &theVerts){vertices.push_back (theVerts);}

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

//Body

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

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

抱歉说得太模糊了;一位讲师刚刚给我们提供了一个简单的流插入示例,然后就让我们自己思考了。

I'm trying to write an overloaded stream insertion operator for a class who's only member is a vector. It's a vector of Points, which is a struct containing two doubles.
I figure what I want is to insert user input (a bunch of doubles) into a stream that I then send to a modifier method. I'm working off other stream insertion examples such as:

std::ostream& operator<< (std::ostream& o, Fred const& fred)
 {
   return o << fred.i_;
 }

but when I try something similar:

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

I get an error "no match for operator >> etc etc." If I leave off the .vertices, it compiles, but I figure that's not right. (By the way, vertices is the name of my vector <Point>.) And even if it is right, I don't actually know what syntax to use in my program to use it, and I'm also not 100% sure on what my modifier method needs to look like.

Here's my Polygon class:

//header

#ifndef POLYGON_H
#define POLYGON_H
#include "Segment.h"
#include <vector>
class Polygon
{
 friend std::istream & operator >> (std::istream &inStream, Polygon &vertStr);
 public:
   //Constructor
    Polygon(const 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 (int) vertices.capacity();}
    //add Point elements to vector
    inline void setVertices(const Point &theVerts){vertices.push_back (theVerts);}

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

//Body

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

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

Sorry to be so vague; a lecturer has just kind of given us a brief example of stream insertion and then left us on our own.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流年里的时光 2024-09-04 04:19:19

问题是向量没有标准的提取运算符(插入到流中,从流中提取),因此您需要定义自己的运算符。此外,流默认情况下会跳过空格,因此您通常不需要使用 std::ws。您没有定义矢量输入如何终止,因此我假设换行符表示矢量的结尾。

由于这是学校的问题,我不能给你太多。首先,您需要填写以下一些声明,其中一些内容可能会很有用。导入命名空间 std 是一种不好的形式,因此以下内容不会。

#include <list>

// returns true if ch is a horizontal space. Locales are a little tricky,
// so you could skip them for now and instead start with the functions defined 
// in header <ctype>
bool ishs(char ch, std::locale loc=std::locale::global());
// return true if ch is a vertical space
bool isvs(char ch);
// return true if the next character in stream 'in' is a vertical space.
bool eol(std::istream& in);

// reads & discards horizontal spaces
std::istream& hs(std::istream& in);

class Point {
public:
  // Scalar is so you can use 'Point::Scalar' rather than 'double', 
  // making it easy should you which to change the type that a Point holds.
  // When you've covered templates, this will make it trivial to templatize Point.
  typedef double Scalar;
  ...
};

class Polygon {
public:
     // adds pt as the last of this polygon's vertices
     // Note: this is basically your "setVertices" with a different name
   Polygon& append(const Point& pt);
     // adds the points from 'start' to 'end' to this polygon
   template <typename _Iter>
   Polygon& append(_Iter start, _Iter end);
     // remove all points in this polygon
   void erase();
     // returns the number of sides on this polygon, 
     // which is also the number of vertices
     // Note: this is different from your "sizeOfVect"; see below for more
   int sides() const { return vertices.size(); }
     // set aside space for polygon to have 's' sides.
   voids sides(int s) { vertices.resize(s); }
}

/* reads the next two numbers on the current line into pt.
   Throws an exception if there is only one number.
 */
std::istream& operator>>(std::istream& in, Point& pt);
/* reads numbers on the current line into points on 'poly'.
   Throws an exception if there is only one number. Preferably,
   won't alter 'poly' if there are an odd amount of numbers.

   you could also put the contents of this operator into >>(istream&, Polygon&)
 */
std::istream& operator>>(std::istream& in, std::vector<Point>& vertices) {
    std::list<Point::Scalar> points;
    Point pt;
    // while not at eol(in), read into pt and add it to points
    // After that, empty vertices, then add the Points in points to vertices
    ...
}

作为字符相关函数(ishsisvshseol)的替代方法,您可以阅读将下一行转换为 getline 的字符串,然后进入 istringstream 并从中读取点。当 istringstream 到达 eof< 时向量结束/code>(或 string >> pt 为 false)。

您需要做的是将operator>>(istream&, vector&)中的任务转换为方法和函数调用,然后:

  1. 声明新的方法和函数。
  2. 编写任务的描述(如 >> 注释中所做的那样)。
  3. 将描述转化为方法和函数调用。
  4. 重复此操作,直到不再需要编写新方法或函数。

为什么我的 Polygon::sides() 与您的 Polygon::sizeOfVect() 不同:请注意,vector::capacity 返回的数量向量可以在不调整大小的情况下容纳的元素;也就是说,它基本上是 sizeof(vect)/typeof(element)。 vector::size 是当前存储在向量中的元素数量。如果您为元素预先分配空间(例如 Polygon::sides(int)),或者如果您从后面弹出元素,则两者可能会有所不同。但无论如何,vector::capacityvector::size

The problem is there is no standard extraction operator for vectors (insertion is to a stream, extraction from a stream), so you'll need to define your own. Also, streams skip whitespace by default, so you don't generally need to use std::ws. You didn't define how vector input is terminated, so I'm assuming a newline indicates the end of a vector.

Since this is a school problem, I can't give you too much. To start, here are some declarations for you to fill out, and some includes that might prove useful. It's bad form to import namespace std, so the following doesn't.

#include <list>

// returns true if ch is a horizontal space. Locales are a little tricky,
// so you could skip them for now and instead start with the functions defined 
// in header <ctype>
bool ishs(char ch, std::locale loc=std::locale::global());
// return true if ch is a vertical space
bool isvs(char ch);
// return true if the next character in stream 'in' is a vertical space.
bool eol(std::istream& in);

// reads & discards horizontal spaces
std::istream& hs(std::istream& in);

class Point {
public:
  // Scalar is so you can use 'Point::Scalar' rather than 'double', 
  // making it easy should you which to change the type that a Point holds.
  // When you've covered templates, this will make it trivial to templatize Point.
  typedef double Scalar;
  ...
};

class Polygon {
public:
     // adds pt as the last of this polygon's vertices
     // Note: this is basically your "setVertices" with a different name
   Polygon& append(const Point& pt);
     // adds the points from 'start' to 'end' to this polygon
   template <typename _Iter>
   Polygon& append(_Iter start, _Iter end);
     // remove all points in this polygon
   void erase();
     // returns the number of sides on this polygon, 
     // which is also the number of vertices
     // Note: this is different from your "sizeOfVect"; see below for more
   int sides() const { return vertices.size(); }
     // set aside space for polygon to have 's' sides.
   voids sides(int s) { vertices.resize(s); }
}

/* reads the next two numbers on the current line into pt.
   Throws an exception if there is only one number.
 */
std::istream& operator>>(std::istream& in, Point& pt);
/* reads numbers on the current line into points on 'poly'.
   Throws an exception if there is only one number. Preferably,
   won't alter 'poly' if there are an odd amount of numbers.

   you could also put the contents of this operator into >>(istream&, Polygon&)
 */
std::istream& operator>>(std::istream& in, std::vector<Point>& vertices) {
    std::list<Point::Scalar> points;
    Point pt;
    // while not at eol(in), read into pt and add it to points
    // After that, empty vertices, then add the Points in points to vertices
    ...
}

As an alternative to the character related functions (ishs, isvs, hs, eol), you can read the next line into a string with getline, thence into an istringstream and read points from that. The vector ends when the istringstream reaches eof (or strin >> pt is false).

What you need to do is turn the tasks in operator>>(istream&, vector<Point>&) into method and function calls, then:

  1. Declare the new methods and functions.
  2. Write a description of the tasks (as is done in the >> comment).
  3. Turn the description into method and function calls.
  4. Repeat until there are no more new methods or functions to write.

Why my Polygon::sides() is different from your Polygon::sizeOfVect(): note that vector::capacity returns the number of elements a vector can hold without resizing; that is, it's basically sizeof(vect)/typeof(element). vector::size is the number of elements currently stored in a vector. The two might differ if you preallocate space for elements, such as Polygon::sides(int) does, or if you pop elements off the back. No matter what, however, vector::capacityvector::size.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文