Why declare an overloaded operator in a class?

I tried the code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;

class Greeter
{
private:
    string name;
public:
    Greeter(string name2)
    {
        name = name2;
    }
    Greeter()
    {
        cout << "What's your name?" << endl;
        getline(cin,name);
    }
    void setname(string name2)
    {
        name = name2;
    }
    string getname()
    {
        return name;
    }
    void greet()
    {
        cout << "Hello, " << name << "!" << endl;
    }
};

ostream& operator << (ostream& out,Greeter Bill)
{
    out << Bill.getname();
    return out;
}

int main()
{
    Greeter me("Fez");
    cout << me << endl;
    return 0;
}


and it worked fine. Note that I didn't declare the operator << in the Greeter class.

So why do I see people doing so all the time? I'm sure there's some reason that I'm overlooking, maybe better organized code. I thought it might've been because then you might be able to access private/protected fields, but

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
using namespace std;

class Greeter
{
private:
    string name;
public:
    Greeter(string name2)
    {
        name = name2;
    }
    Greeter()
    {
        cout << "What's your name?" << endl;
        getline(cin,name);
    }
    void setname(string name2)
    {
        name = name2;
    }
    string getname()
    {
        return name;
    }
    void greet()
    {
        cout << "Hello, " << name << "!" << endl;
    }
    ostream& operator << (Greeter);
};

ostream& operator << (ostream& out,Greeter Bill)
{
    out << Bill.name;
    return out;
}

int main()
{
    Greeter me("Fez");
    cout << me << endl;
    return 0;
}


didn't work.
Last edited on
Your overloaded function uses the private member 'name' without being a member function.

To do this you'll need to use the friend keyword.

In line 30, use:
friend ostream& operator << (ostream&, Greeter);

I things will work for you better.


As for why people use it? It can be more intuitive to use the object with a cout << directly instead of using a get function. Here's a class that hold complex numbers as an example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Complex
{
private: 
    double real;
    double imag;
public:
    friend ostream& operator << (ostream& , Complex);
};

ostream& operator << (ostream& out, Complex c)
{
    out << c.real << " + " << c.imag << 'i';
    return out;
}
Last edited on
You may have misunderstood my question. Mistake on my part, I phrased it badly. What I was asking was why declare it in the class as opposed to outside the class? But the friend keyword makes sense, thanks.
Anything declared inside of a class tends to be cleaner in C++. Otherwise, it's a little more difficult to keep all of your functions in one place if you're using a hundred source files for your project.

This sort of thing may not be incredibly useful if your building a project with one or two source files, but when complexity increases or if you ever start integrating external libraries, you'll be glad that you've done stuff like this.

It's hard to remember everything about each one of your classes, so if you make them more intuitive to work with, you and the other programmers on your project will be much more useful.
Last edited on
You can only declare operator<< as a member of Greeter if you want the first argument to be of type Greeter&. In this case you want the first argument to be of type std::ostream& so you have to declare it outside the Greeter class.
Peter87 wrote:
You can only declare operator<< as a member of Greeter if you want the first argument to be of type Greeter&. In this case you want the first argument to be of type std::ostream& so you have to declare it outside the Greeter class.


Really?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;

class ExampleClass
{
    ostream& operator << (ExampleClass);
};

ostream& operator << (ostream& out,ExampleClass MyObject)
{
    out << "This is a sample." << endl;
    return out;
}

int main()
{
    ExampleClass Object;
    cout << Object << endl;
    return 0;
}


I just declared it inside the ExampleClass class, even thought its first argument was ostream&. However, I didn't define it in ExampleClass. Is that what you mean?
Last edited on
That's right.

An overloaded function in a class assumes that this class will be on the left side. In an example where we have a ostream object on the left, you need to declare a friend function instead. In a friend function or any overloaded function declared outside of the scope of a class, the first argument represents the left-hand side and the second argument represents the right-hand side of the operator.
What about:
1
2
3
4
class foo
{
       ostream& operator<<(ostream& stm, foo);
       };
?
I'm pretty sure that would work(after, ofcouse you actualy declare the operator.
I don't think that would work viliml.

You would get an error that this function expects only one argument. That's because the left-hand side of the argument is *this implicitly when defined within the scope of the class.
Topic archived. No new replies allowed.