从重载运算符返回对象>>

时间:2017-11-03 09:42:44

标签: c++

C ++不是我的第一语言选择。而且我不知道我是否认为完全错了。

到目前为止我创造了什么。

我有一个属性的类。指向类Shape的指针。我把类命名为ShapePtr。

ShapePtr.h

class ShapePtr{
    public:

        ShapePtr():sPtr(0){};
        ShapePtr(Shape *s):sPtr(s){};
        ShapePtr(const ShapePtr *s){
            if( s->sPtr != 0 )
                sPtr = s->sPtr->clone();
            else
                sPtr = 0;
            };

        friend std::istream& operator>>(std::istream& is, const ShapePt &s);

        Shape *sPtr; //Points on Shape or 0

    };

ShapePtr.cpp

std::istream& operator>>(std::istream& is, const ShapePtr &s){

        std::size_t found;
        std::string row, theShape;

        while(!is.eof()){

            getline(is,row);
            found = row.find(":");
            theShape= row.substr(0,found);

            if(theShape.compare("CIRKEL") == 0)
            {

                ShapePtr tempSPtr = ShapePtr(new Circle);
    /*return*/  ShapePtr test = ShapePtr(tempSPtr.sPtr -> creat(row));

            }else if(theShape.compare("POLYGON") == 0){
                /*...*/
            }else if(theShape.compare("RECTANGLE") == 0){
                /*...*/
            }else if(theShape.compare("POINT") == 0){
                /*...*/
            }
             /*else if ...*/

        };

Class Shape,它是一个带有虚函数creat()的抽象基类。

Shape.h

class Shape{
    public:
        virtual Shape* creat(std::string row) = 0;
};

Circle是具有不同形状的众多子类之一。

Circle.h

class Circle : public Shape{
    public:
        Circle();
        Circle( double x, double y, double r) : Shape(x, y), radie(r){};

        Shape *creat(std::string row);

    private:
        double radie;
};

Circle.cpp

Circle::Circle()
: Shape(0, 0), radie(0)
{};

Shape * Circle::creat(std::string row){

    std::size_t found1, found2;
    std::string xstr, ystr, rstr;
    double xd, yd, rd;

    found1 = row.find("(");
    found2 = row.find(",");

    //X position
    xstr = row.substr(found1 + 1,found2 - found1 -1);

    found1 = row.find(",");
    found2 = row.find(")");

    //Y position
    ystr = row.substr(found1 +1,found2 -found1 -1);

    found1 = row.find_last_of(":");

    //Radie
    rstr = row.substr(found1 + 1);

    //To double
    xd = atof(xstr.c_str());
    yd = atof(ystr.c_str());
    rd = atof(rstr.c_str());

    return new Circle(xd, yd, rd);
};

我的问题是我希望能够使用ShapePtr覆盖运算符>>读取main文件。然后我想重新调整ShapePtr函数中创建的对象。在我上面的代码中,该对象称为test。我在同一行写了一条评论/ return /来澄清。在main中,此对象将添加到列表中。

我无法更改运算符>>返回ShapePtr而不是istream,因为它不再被覆盖。

main应该是这样的

int main(){

    ifstream is("fil.dat");
    istream_iterator<ShapePtr> shapein(is), endofshapein;
    list<ShapePtr> shapelist(shapein, endofshapein );
}

fil.dat的外观如何

POLYGON: { (0,0) (10,0) (5,2) (5,5) }
CIRKEL: (5,5) Radie:4
RECTANGLE: (4,10) Hight:4 Width:2
POINT: (6,7) :1

澄清我的问题。阅读和创建形状不是问题。它们已创建,可以在ShapePtr中打印。问题是如何将它们放到main中的列表中。它可以完成还是我从一开始就创建了很多不好的代码?

我显然没有在论坛上写下我的所有代码,反正我可能写得太多了。但是我写得太多而不是太少。

提前感谢您的回复。

1 个答案:

答案 0 :(得分:1)

您并非习惯性地覆盖std::istream& operator>>,因此std::istream_iterator将无法做正确的事。

正确的签名是std::istream& operator>>(std::istream& is, ShapePtr &s)。完成后,您可以分配到sreturn is;

std::istream& operator>>(std::istream& is, ShapePtr &s){
    std::string row;

    if(getline(is,row)) {
        std::size_t found = row.find(":");
        std::string theShape = row.substr(0, found);

        if(theShape.compare("CIRKEL") == 0){
            Circle c; 
            s = c.create(row);
            return is;
        } else if(theShape.compare("POLYGON") == 0){
            /*...*/
        } else if(theShape.compare("RECTANGLE") == 0){
            /*...*/
        } else if(theShape.compare("POINT") == 0){
            /*...*/
        } /*else if ...*/
    }
    return is;
}

但是你的设计存在很多其他问题,比如Circle::create是一个返回new Circle而不是构造函数的成员函数,因为你使用原始指针而泄漏Shapes并且不要注意delete的事情等。