nacho4d
nacho4d

Reputation: 45138

Overloading << operator in C++

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

Upvotes: 2

Views: 1506

Answers (6)

David Thornley
David Thornley

Reputation: 57066

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.

Upvotes: 16

James Curran
James Curran

Reputation: 103565

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

Upvotes: 0

Lucas Arbiza
Lucas Arbiza

Reputation: 273

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;

Upvotes: 0

Steve Townsend
Steve Townsend

Reputation: 54178

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.

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254721

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

Upvotes: 9

Marcin Deptuła
Marcin Deptuła

Reputation: 11977

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.

Upvotes: 3

Related Questions