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 ...*/

        };


类Shape是具有虚拟函数creat()的抽象基类。

形状

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


圆形,是具有不同形状的许多子类之一。

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重写的运算符>>读取主文件。然后,我想重新调整在ShapePtr函数中创建的对象。在上面的代码中,该对象称为test。我在同一行写了一个注释/ return /来澄清。总的来说,该对象将被添加到列表中。

我无法更改operator >>以返回ShapePtr而不是istream,因为那样便不再覆盖它。

主要应该是这样的

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列表。是可以做到的,还是我从一开始就创建了很多不好的代码?

我显然没有在论坛上写所有代码,反正我可能写太多了。但是我宁愿写太多也不愿写太多。

预先感谢您的答复。

最佳答案

您不是习惯性地覆盖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,因为您使用的是原始指针并且对的东西等

关于c++ - 从重载运算符返回对象>>,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47092588/

10-09 13:34