tags:

views:

163

answers:

6

I want to overload << operator in a Line class so I can print an object using cout like this:

cout << myLineObject << endl;

but this is not working:

class Line{
public:
    float m;
    float b;
    string operator << (Line &line){return ("y = " + line.m + "x + " + line.b);};
};

I get:

Invalid operands of types 'const char [5]' and 'float' to binary 'operator+'

I also tried with stringstream but I get even more errors. What is the correct way of doing this?

Thanks ;)

+3  A: 

Googled this one, looks fine: Overloading <<

Basically, when overloading << operator for IO, your function should look like this:

friend ostream& operator<<(ostream& output, const YourClassHere& p);

Notice, that operator<< is not a class member, but a external function (which can be friend if you need it to be). Such function should use output to write to it and then return it, so you can chain it.

Ravadre
That's the right declaration, but you didn't address the problems in the body of the function.
David Thornley
Ravadre
+16  A: 

The correct way is listed everywhere overloading << is discussed, and you've managed to miss pretty much all of it.

The standard declaration is ostream & operator<<(ostream & s, const & Line l); It cannot be a member function, and it needs to return a reference to the ostream so that you can chain << as normal.

The definition, in your case, would be something like

ostream & operator<<(ostream & s, const & Line l)
{
    return s << "y = " << l.m << "x + " << l.b;
}

Note that you return the incoming ostream, and print what you like using the << operator rather than using the + operator. It's pretty simple if you follow this form.

In this case, the data members are public (which is not a good idea in general), so there's no access problems. If you need to get inaccessible values (because they're private and not exposed in the public interface), you'll need to declare the operator to be a friend in the class definition.

David Thornley
`l` should be `line` for the second argument (or `line` should be `l` in the function body).
Steven Oxley
@Steven: Thank you. I've edited to match.
David Thornley
+8  A: 

operator<< has to be a non-member function, since the stream is the left-hand argument. In your case, since the data members are public, it can be implemented outside the class:

std::ostream& operator<<(std::ostream& stream, const Line& line)
{
    return stream << "y = " << line.m << " x = " << line.b;
}
Mike Seymour
A: 

The error here is nothing to do with the operator overloading, though once resolved you may have more questions on that. This error happens because there is no operator+ defined that takes arguments of const char[5] and float. Since you are trying to concatenate the string forms of those four args

"y = " + line.m + "x + " + line.b

you have to do this in a way the compiler can understand e.g.

ostringstream concat;
concat << string("y = ") << line.m << string("x + ") << line.b;
return concat.str();

Once you get past this, you can work on your << overloading logic.

Steve Townsend
A: 

You can do this way:

   class Line{
    public:
    float m;
    float b;
    friend ostream& operator<< (ostream& out, Line& object) {
    out << object.m << endl;
    out << object.b << endl;
    return out;
    }
};

Then you can do: cout << your_Line_object << endl;

Lucas Arbiza
A: 

Other have explained the correct way. I figured I'd mention what you are doing wrong.

You define an operator which takes two Line objects:

 Line a;
 Line b;
 string c = a << b;  
 // c would have the string values for line b
 // the values of line a would be ignored.

Of course, that's not the error you are seeing. That's caused by the line "y = " + line.m. "y = " is a char[5]. amd line.m is a float, and there is no operator+ which takes those two (This ain't Basic -- or C#).

The problem is that C++ has no easy way to "add" non-string values to a string. Which is why we use the convention of cout <<.

James Curran