By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,187 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

Confused with friendly operator overloading

P: n/a
Iv'e been reading tutorials and articles describeing operator
overloading as both member functions and friend functions. I don't
understand however the purpose of the friend on an operator when the
operator already has access to the private data of a class since it is
a member. So why add the keyword friend.

What I do understand is that declareing a class or function as a friend
alows the friend to access private data without accessors. And I
understand that operator overloading gives us the ability to implement
common operators such as + and = on our user defined class objects.

Can somebody explain to me why a friend operator is so special?

Jul 23 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Kelly Mandrake wrote:
Iv'e been reading tutorials and articles describeing operator
overloading as both member functions and friend functions. I don't
understand however the purpose of the friend on an operator when the
operator already has access to the private data of a class since it is
a member. So why add the keyword friend.
If you declare a function a friend, it's not a member. You've been either
misinformed of the meaning and the role of the friend declaration or you
read wrong tutorials.
What I do understand is that declareing a class or function as a friend
alows the friend to access private data without accessors. And I
understand that operator overloading gives us the ability to implement
common operators such as + and = on our user defined class objects.

Can somebody explain to me why a friend operator is so special?


A non-member function has to be declared "friend" to gain access to
private members of the class.

V
Jul 23 '05 #2

P: n/a
Thanks, I already understand that declareing friend gives the non
member access to my private data but what confuses me is the reason for
declareing an operator as a friend such as in this example I dont see
the reason for the friend keyword

#include
using namespace std;
class threenums {
int a, b, c;
public:
threenums() {a=b=c=0;}
threenums(int x, int y, int z) {a=x; b=y; c=z;}
friend threenums operator+(threenums o1, threenums o2);
threenums operator=(threenums o2);
void display();
};
threenums operator+(threenums o1, threenums o2)
{
threenums num;
num.a = o1.a + o2.a;
num.b = o1.b + o2.b;
num.c = o1.c + o2.c;
return num;
}
threenums threenums::operator=(threenums o2)
{
a = o2.a;
b = o2.b;
c = o2.c;
return *this;
}
void threenums::display()
{
cout << a << ", ";
cout << b << ", ";
cout << c << '\n';
}
int main()
{
threenums x(5, 10, 15), y(10, 15, 20), z;
x.display();
y.display();
z = x + y;
z.display();
z = x + y + z;
z.display();
z = x = y;
x.display();
y.display();
z.display();
return 0;
}

Jul 23 '05 #3

P: n/a
Kelly Mandrake wrote:
Thanks, I already understand that declareing friend gives the non
member access to my private data but what confuses me is the reason for
declareing an operator as a friend such as in this example I dont see
the reason for the friend keyword

#include
using namespace std;
class threenums {
int a, b, c;
public:
threenums() {a=b=c=0;}
threenums(int x, int y, int z) {a=x; b=y; c=z;}
friend threenums operator+(threenums o1, threenums o2);
Remove the 'friend' declaration from the class and see what the compiler
says to that.
threenums operator=(threenums o2);
void display();
};
threenums operator+(threenums o1, threenums o2)
{
threenums num;
num.a = o1.a + o2.a;
num.b = o1.b + o2.b;
num.c = o1.c + o2.c;
return num;
} [...]


V
Jul 23 '05 #4

P: n/a
REH

"Kelly Mandrake" <at******@gmail.com> wrote in message
news:11*********************@g14g2000cwa.googlegro ups.com...
Thanks, I already understand that declareing friend gives the non
member access to my private data but what confuses me is the reason for
declareing an operator as a friend such as in this example I dont see
the reason for the friend keyword

#include
using namespace std;
class threenums {
int a, b, c;
public:
threenums() {a=b=c=0;}
threenums(int x, int y, int z) {a=x; b=y; c=z;}
friend threenums operator+(threenums o1, threenums o2);
threenums operator=(threenums o2);
void display();
};


In this example, operator+ is not a member, but a friend. If it were a
member, you would only give it one parameter because the other would be
"this."

Jul 23 '05 #5

P: n/a
Oooh...I think you finaly got through to me...

I never saw that the classname:: was missing in the operator+
definition.

I removed friend and I see that the compiler complains about haveing
more then one parameter. And it also complains about accessing private
data. From this I can gather that when declared as a friend the
operator is passed 2 parameters where it is passed only one if not a
friend. I can also gather that because it is declared as a friend, it
must be external and when I took a closer look at the definition of
operator + I see that the classname:: is missing which I did not notice
before

I think now its starting to make secne. So I must be overloading a
global operator+ and because it is not a member of my class, it must be
declared as a friend so it can access my private data and this gives
the ability to add two differnt objects because when two diff objects
are added they call the global + operator and now I can build a handler
especialy for that.

Is this correct?

Jul 23 '05 #6

P: n/a
Kelly Mandrake wrote:
Oooh...I think you finaly got through to me...

I never saw that the classname:: was missing in the operator+
definition.

I removed friend and I see that the compiler complains about haveing
more then one parameter. And it also complains about accessing private
data. From this I can gather that when declared as a friend the
operator is passed 2 parameters where it is passed only one if not a
friend. I can also gather that because it is declared as a friend, it
must be external and when I took a closer look at the definition of
operator + I see that the classname:: is missing which I did not notice
before

I think now its starting to make secne. So I must be overloading a
global operator+ and because it is not a member of my class, it must be
declared as a friend so it can access my private data and this gives
the ability to add two differnt objects because when two diff objects
are added they call the global + operator and now I can build a handler
especialy for that.

Is this correct?


Yes, pretty much. However, if you actually think about it, you don't
really need the non-member operator+ to be a friend. If you implement
the += operator (and it should be a member, since it changes the object
for which it's called), then you can implement operator+ this way:

threenums operator +(threenums const &one, threenums const& two)
{
threenums result(one);
return result += two;
}

Also, note that your operator= does not have the proper signature. The
language creates the default one with the signature

threenums& operator=(threenums const&);

and yours for whatever reason needs its argument by value and returns
its result by value. Too much Java(tm)?

Read about the advantage of passing by const reference versus passing by
value. The FAQ should be helpful there. If not, see the archives.

V
Jul 23 '05 #7

P: n/a
Very interesting, so with this method, it is realy asking the object
itself to preform its own operator+= this way the global operator does
not need access to the private data since operator+= is a member
function and has acess to its own private data.

Thanks very much for the help everyone. It all makes sence now, and I
just created two vector classes one that has x y z and one that just
has x and y values then I implemented a operator+ that can add two
difernt vector objects. Im gona try some more examples I found.

I greatly apreciate the help.

Jul 23 '05 #8

P: n/a
Kelly Mandrake wrote:
Thanks, I already understand that
declaring friend gives the non member access to my private data
but what confuses me is the reason for declaring an operator as a friend
such as in this example
I don't see the reason for the friend keyword. cat example.cc #include <iostream>

class threenums {
private:
// representation
int a, b, c;
public:
// member operators
threenums&
operator=(const threenums& o2);
threenums
operator-(const threenums& o2) const;
// friend operators
friend
threenums
operator+(const threenums& o1, const threenums& o2);
friend
std::ostream&
operator<<(std::ostream& os, const threenums& t);
// constructors
threenums(int x = 0): a(x), b(x), c(x) { }
threenums(int x, int y, int z): a(x), b(y), c(z) { }
};

inline threenums&
threenums::operator=(const threenums& o2) {
a = o2.a;
b = o2.b;
c = o2.c;
return *this;
}

inline threenums
threenums::operator-(const threenums& o2) const {
return threenums(a - o2.a, b - o2.b, c - o2.c);
}

inline threenums
operator+(const threenums& o1, const threenums& o2) {
return threenums(o1.a + o2.a, o1.b + o2.b, o1.c + o2.c);
}

inline std::ostream&
operator<<(std::ostream& os, const threenums& t) {
return os << t.a << ", " << t.b << ", " << t.c;
}

int
main(int argc, char* argv[]) {
threenums x(5, 10, 15), y(10, 15, 20), z = x + y;
std::cout << "x = " << x << std::endl;
std::cout << "y = " << y << std::endl;
std::cout << "x + y --> z = " << z << std::endl;
z = x + y + z;
std::cout << "x + y + z --> z = " << z << std::endl;
z = x = y;
std::cout << "y --> x --> z" << std::endl;
std::cout << "x = " << x << std::endl;
std::cout << "y = " << y << std::endl;
std::cout << "z = " << z << std::endl;
return 0;
}
g++ -Wall -ansi -pedantic -o example example.cc
./example

x = 5, 10, 15
y = 10, 15, 20
x + y --> z = 15, 25, 35
x + y + z --> z = 30, 50, 70
y --> x --> z
x = 10, 15, 20
y = 10, 15, 20
z = 10, 15, 20

Notice that I have included a new [implicit] constructor

threenums(int x = 0): a(x), b(x), c(x) { }

This allows mixed operands

y - 13

for member operator- as long as the left operand is a threenums.
For friend operator+, either operand may be an int

y + 13

or
13 + y

as long as the other operand is a threenums.
If you mean to disallow mixed operands,
you can make operator+ a member as well.
Jul 23 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.