Friend and const doubts

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
#include <iostream>

using namespace std;

class Comp{
private:
    float r, i;
public:
    Comp(): r(0),i(0){}
    Comp(float tempReal, float tempImg): r(tempReal), i(tempImg){}
    float real(){ return r; }
    float img(){ return i; }
    /*friend*/ ostream& operator<<( ostream& out, /*const*/ Comp& tempComp) /*const*/ {
        return out<<tempComp.real()<<" + i*"<<tempComp.img();
    }
    Comp operator+(/*const*/ Comp& c2) const{
        return Comp(r+c2.real(),i+c2.img());
    }
};

int main(){

    Comp a(1,2);
    Comp b(3,4);
    cout<<a+b<<endl;
    return 0;
}


The "friend" comment is needed for the code to compile, but i don't see why i need it. The other "const" comments are things that i feel like would make sense, but i can't figure out a way to implemet them.
Also, how can i make the main work?
Last edited on
Consider: Comp a; cout<<a;
The statment cout<<a uses two objects, the ostream class object cout and the Comp object a. If you did not have friend you'd have either:
1. a class method: if the overloaded operator was a class method you'd have to use it in the following way:
a<<cout which would be confusing and counter-intuitive and would also prevent concatenation of the form cout<<a<<b etc ...

2. a non-member, non-class function: OK in that case you could have cout<<a but then you're not able to access the object's private data-members directly. So in your example instead of cout<<a.r you'd have to write cout<<a.getR() where getR() is a getter method that returns r and so on

On line 13 of your program the first const ensures that the operator << does not change the Comp object tempComp in any way. The second const on that line is not needed as it is a friend function not being invoked by a class object. This second const in used when a class object invokes a member method and ensures that the method does not in any way change the invoking object

On line 16 both consts are good practice, the first one ensures Comp c2 is not changed in any way and the second one ensures that the invoking object (*this) is also not changed in any way by the application of operator +
Change your code to be const-correct. Make operator<< a non-member function. A member function, by definition, must take as its implicit first argument a pointer to a class instance of the class it is a member of, but such a definition will not match the signature we need to match to use operator<< as we wish to.

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
#include <iostream>

using namespace std;

class Comp {
private:
    float r, i;
public:
    Comp() : r(0), i(0) {}
    Comp(float tempReal, float tempImg) : r(tempReal), i(tempImg) {}
    float real() const { return r; }
    float img() const { return i; }
    Comp operator+(const Comp& c2) const {
        return Comp(r + c2.real(), i + c2.img());
    }
};

ostream& operator<<(ostream& out, const Comp& tempComp) {
    return out << tempComp.real() << " + i*" << tempComp.img();
}


int main() {

    Comp a(1, 2);
    Comp b(3, 4);
    cout << a + b << endl;
    return 0;
}


Last edited on
Thank you both, gunnerfunner und cire. I manage to make it the way i wanted.
Topic archived. No new replies allowed.