MOHAMED
MOHAMED

Reputation: 43598

compilation error when I overload cout operator inside the class

compilation error when I overload cout operator inside the class

What I am missing?

Here after the source code. The problem disappear when I define the overload operator outside the class

#include <iostream>
using namespace std;

class Box {
    public:
                int l, b, h;
        Box(int length, int breadth, int height) : l(length), b(breadth), h(height) {}
#if 1
        ostream& operator<<(ostream& os) {
            os << (l * b * h);
            return os;
        }
#endif
};

#if 0
ostream& operator<<(ostream& os, Box inb) {
    os << (inb.l * inb.b * inb.h);
    return os;
}
#endif


int main(void) {
    Box B(3,4,5);
        cout << B << endl;
    return 0;
}

Upvotes: 0

Views: 73

Answers (3)

NathanOliver
NathanOliver

Reputation: 181027

You can't overload operator << that way and have it work like normal. When you have

ostream& operator<<(ostream& os) {
    os << (l * b * h);
    return os;
}

What you really have is

ostream& operator<<(Box& this_, ostream& os) {
    os << (this_.l * this_.b * this_.h);
    return os;
}

Which means you would need to call cout like

B << cout << endl;

The reason for this is that all class member functions have an implicit parameter of a reference type to the class as their first parameter. The compiler inserts this for you as that is how the member function knows which object to work on.

Upvotes: 1

aschepler
aschepler

Reputation: 72473

The expression X << Y (when at least one operand has class or enum type) looks for whether operator<<(X, Y) or X.operator(Y) can be called.

So in cout << B, it looks for operator<<(cout, B) and cout.operator<<(B). Notice it's not at all looking for members of B. It looks for members of cout, but you can't add new members to a standard library class. So you need to define the non-member function.

The member you did define would make B << std::cout << std::endl; work, but that doesn't look right, obviously.

One other option, necessary if the operator needs to use private members of the class, or nice if we just want the operator visible in the class's public section, is to declare it a friend, which is really a non-member:

class Box {
public:
    Box(int length, int breadth, int height) : l(length), b(breadth), h(height) {}

    friend std::ostream& operator<<(ostream& os, const Box& box) {
        os << (box.l * box.b * box.h);
        return os;
    }

private:
    int l, b, h;
};

Upvotes: 1

Ted Lyngmo
Ted Lyngmo

Reputation: 118017

The member function:

ostream& operator<<(ostream& os);

would be useful in this case:

boxobject << os;

which is rarely what you want to do. Instead, you need this free function:

std::ostream& operator<<(std::ostream& os, const Box& inb) {
    os << (inb.l * inb.b * inb.h);
    return os;
}

Upvotes: 5

Related Questions