简体   繁体   中英

C++ ostringstream strange behavior when chaining in cout is used

I am a C++ beginner ( came from Java ). I have the following code:

//#include <boost/algorithm/string.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <string.h>
#include <string>
#include <bitset>
#include <algorithm>
#include <sstream>
#include <memory>
#include <assert.h>
#include <cctype>

using namespace std;

class Point{
private:
    int x;
    int y;
public:
    Point(int x,int y){
        this->x=x;
        this->y=y;
    }

    int getX(){
        return x;
    }

    int getY(){
        return y;
    }

    operator const char*(){
        return toString().c_str();
    }

    string toString(){
        ostringstream stream;
        stream<<"( "<<x<<", "<<y<<" )";
        return stream.str();
    }
};


class Line{
private:
    Point p1=Point(0,0);
    Point p2=Point(0,0);

public:
    Line(Point p1, Point p2){
        this->p1=p1;
        this->p2=p2;
    }

    Point getP1(){
        return p1;
    }

    Point getP2(){
        return p2;
    }

    operator const char*(){
        ostringstream stream;
        stream<<"[ "<<p1<<" -> "<<p2<<" ]";
        return stream.str().c_str();
    }

    //    operator const char*(){
    //        ostringstream stream;
    //        stream<<"[ "<<p1<<" -> ";
    //        stream<<p2<<" ]";
    //        return stream.str().c_str();
    //    }
};

int main()
{

    Line line=Line(Point(1,2), Point(3,4));
    cout<<line<<endl;


    cout<<"\nProgram exited successfully."<<endl;
    return 0;
}

I have redefined the operator const* so that I can use cout<

But, If I run the program as it is now, with the second block commented out ( I have 2 versions of operator const*, and by default the second one is commented out ) ,it will display

[ (1, 2) -> (1, 2) ]

But when running with the second block uncommented, the output is as expected:

[ (1, 2) -> (3, 4) ]

The issue seems to occur when I display both Point objects in the same line ( some kind of chaining, though I don't know if chaining is the right word here )

My question, is,why is this happening?

UPDATE

I have added the std::ostream& operator << function to my Line class but now I'm receiving the following errors:

/home/ryu/qt_workspace/hello/main.cpp:67: error: 'std::ostream& Line::operator<<(std::ostream&, const Line&)' must take exactly one argument

/home/ryu/qt_workspace/hello/main.cpp:77: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'

Regards, Aurelian

If you want to use cout << , there is a more direct way to do that.

Add this function to Line .

friend std::ostream& operator << ( std::ostream & os, const Line & l ){
    os << "[ " << l.p1 << " -> " << l.p2 << " ]";
    return os;
}

You should also note that your approach was returning invalid memory - this is a significant way that Java differs from C++.

    return stream.str().c_str();  // Danger!

stream was declared in operator const char*() which limits its lifetime to that function. It is destroyed when that scope is exited. As a result, you are returning a pointer to something that no longer exists.

actually I think with C++11 returning the string by value is perfectly fine, so you can do the transfer there instead of using the cstring underneath.

What are move semantics?

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