From: Pat on 4 Dec 2009 17:05 Today I was reviewing some information about operator overloading (http://www.learncpp.com/cpp-tutorial/92-overloading-the-arithmetic-operators/) and the author make the comment that friend functions (as opposed to member functions) were the best way to overload an operator when the operands were not modified. It wasn't clear to me why that would be though (why friend functions are preferred). Clarity? Thanks for any comments on this. -Pat
From: Ulrich Eckhardt on 5 Dec 2009 06:09 Pat wrote: > Today I was reviewing some information about operator overloading [..] > and the author make the comment that friend functions (as opposed to > member functions) were the best way to overload an operator when the > operands were not modified. It wasn't clear to me why that would be > though (why friend functions are preferred). Clarity? There are three aspects to this: 1. functions instead of memberfunctions This gives you the symmetry so that you can create code where the class you're overloading for is on the right side of the operand. A member operator must have the 'this' object on the left otherwise. I guess the author was referring to this. 2. symmetry Using a non-member function allows you to overload operator+ for (T, int), (int, T) or (T, T) in a similar way. This follows from point 1, but is more an aesthetic part. 3. friend instead of non-friend This gives you access to the internals of a type. Further, it allows you to define the operators near to the code where the member operators are and to also define them inline if you want. Uli
From: Kaz Kylheku on 5 Dec 2009 13:00 On 2009-12-05, Ulrich Eckhardt <doomster(a)knuut.de> wrote: > Pat wrote: >> Today I was reviewing some information about operator overloading [..] >> and the author make the comment that friend functions (as opposed to >> member functions) were the best way to overload an operator when the >> operands were not modified. It wasn't clear to me why that would be >> though (why friend functions are preferred). Clarity? > > There are three aspects to this: > 1. functions instead of memberfunctions > This gives you the symmetry so that you can create code where the class > you're overloading for is on the right side of the operand. A member > operator must have the 'this' object on the left otherwise. I guess the > author was referring to this. > 2. symmetry > Using a non-member function allows you to overload operator+ for (T, int), > (int, T) or (T, T) in a similar way. This follows from point 1, but is more > an aesthetic part. > 3. friend instead of non-friend > This gives you access to the internals of a type. So does a static member function. > Further, it allows you to > define the operators near to the code where the member operators are and to > also define them inline if you want. What? A static member function can also be be bear the code where the member operators are. Typically, in the same source files where the class is implemented, but not necessarily. Static functions can be inline too. The real reason for wanting to use friend functions is that a function may be declared as a friend to more than one class, whereas it can be a member of at most one class. An overloaded binary operator may have to peek into the internals of two different classes, and so it needs to be a member of one of them and friend to the other, or friend to both.
From: Francis Glassborow on 7 Dec 2009 07:42 Kaz Kylheku wrote: > On 2009-12-05, Ulrich Eckhardt <doomster(a)knuut.de> wrote: >> Pat wrote: >>> Today I was reviewing some information about operator overloading [..] >>> and the author make the comment that friend functions (as opposed to >>> member functions) were the best way to overload an operator when the >>> operands were not modified. It wasn't clear to me why that would be >>> though (why friend functions are preferred). Clarity? >> There are three aspects to this: >> 1. functions instead of memberfunctions >> This gives you the symmetry so that you can create code where the class >> you're overloading for is on the right side of the operand. A member >> operator must have the 'this' object on the left otherwise. I guess the >> author was referring to this. >> 2. symmetry >> Using a non-member function allows you to overload operator+ for (T, int), >> (int, T) or (T, T) in a similar way. This follows from point 1, but is more >> an aesthetic part. >> 3. friend instead of non-friend >> This gives you access to the internals of a type. > > So does a static member function. Since when? A static member function has no access at all, in any way to instance data, only to static (i.e. class rather than instance) data > >> Further, it allows you to >> define the operators near to the code where the member operators are and to >> also define them inline if you want. > > What? A static member function can also be be bear the code where the > member operators are. Typically, in the same source files where the > class is implemented, but not necessarily. Static functions can be > inline too. I do not understand what you are on about. static member functions have nothing to do with this issue. > > The real reason for wanting to use friend functions is that a > function may be declared as a friend to more than one class, > whereas it can be a member of at most one class. No, the real reason for friends is efficiency. It allows a function to cut corners and directly access an instances data rather than go through access functions. A friend function is essentially part of the classes interface and will need modification any time that the class designer elects to change the data representation. In general, inexperienced programmers would be well advised to keep clear of friend functions until they understand when they are desirable and hence worth paying the maintenance cost. > > An overloaded binary operator may have to peek into the internals of two > different classes, and so it needs to be a member of one of them > and friend to the other, or friend to both. It would be very rare that this was the case. Mostly the class public access functions will be sufficient. Only when performance issues become a major issue should you revisit the use of friend versus public access functions.
From: Kaz Kylheku on 7 Dec 2009 17:37 On 2009-12-07, Francis Glassborow <francis.glassborow(a)btinternet.com> wrote: > Kaz Kylheku wrote: >> On 2009-12-05, Ulrich Eckhardt <doomster(a)knuut.de> wrote: >>> Pat wrote: >>>> Today I was reviewing some information about operator overloading [..] >>>> and the author make the comment that friend functions (as opposed to >>>> member functions) were the best way to overload an operator when the >>>> operands were not modified. It wasn't clear to me why that would be >>>> though (why friend functions are preferred). Clarity? >>> There are three aspects to this: >>> 1. functions instead of memberfunctions >>> This gives you the symmetry so that you can create code where the class >>> you're overloading for is on the right side of the operand. A member >>> operator must have the 'this' object on the left otherwise. I guess the >>> author was referring to this. >>> 2. symmetry >>> Using a non-member function allows you to overload operator+ for (T, int), >>> (int, T) or (T, T) in a similar way. This follows from point 1, but is more >>> an aesthetic part. >>> 3. friend instead of non-friend >>> This gives you access to the internals of a type. >> >> So does a static member function. > > Since when? Since early 1980-something C++, probably. > A static member function has no access at all, in any way to > instance data, only to static (i.e. class rather than instance) data A static member function of a class has access to the private members of that class, static or not. Access means permission not means. To have means of accessing a non-static member, a static member function requires an instance. But that can be obtained. The real reason to use friend functions for overloaded operators (over static functions) is that static functions simply cannot be overloaded operators. It's not in the language. Overloaded operators must be non-static member functions, or non-member functions. They cannot be static members, as I wrongly implied. Oops, sorry about that, everyone! So if for whatever reason you don't want overloaded operators to be member functions, you must make them nonmember functions. If these functions need access to the internals of the class(es) they work with, they have to be friends. That's all there is to it.
|
Next
|
Last
Pages: 1 2 3 4 Prev: Multiplying a complex number by a constant? Next: operator[] in a std::vector like class |