简体   繁体   中英

return object from overloaded operator>>

C++ is not my first language choice. And I do not know if I think completely wrong.

What I have created so far.

I have a class with an attribute. A pointer to the class Shape. I've named the class 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 which is a an abstract base class with a virtual function creat().

Shape.h

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

Circle which is one of many subclasses with different shapes.

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);
};

My problem is that I want to be able to read a file in main with the ShapePtr overrided operator>>. Then I want to retune the object created in the ShapePtr function. In my code above, the object is called test. I have written a comment / return / on the same line to clarify. In main, this object will be added to a list.

I can not change operator>> to return ShapePtr instead of an istream because then it's no longer overrided.

main should look like this

int main(){

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

An example of how fil.dat can look

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

To clarify my problem. To read and create the shapes is not the problem. They are created and can be printed in ShapePtr. The problem is how to get them to the list in main. Can it be done or have I created a lot of code that is bad from the start?

I have obviously not written all my code here in the forum and I may have written too much anyway. But I rather write too much than too little.

Thank you in advance for your reply.

You aren't idiomatically overriding std::istream& operator>> , so std::istream_iterator won't do the right thing.

The correct signature is std::istream& operator>>(std::istream& is, ShapePtr &s) . Once you have that, you can assign to s and return 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;
}

However you have a large number of other problems with your design, like Circle::create being a member function returning a new Circle rather than being a constructor, leaking Shapes because you use raw pointers and don't take care to delete s things etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM