Friend Functions and Interface

I have been reading this article by Scott Meyers:

http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197?pgno=1


specifically this algorithm for determining where functions are put:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if (f needs to be virtual)
   make f a member function of C;
else if (f is operator>> or
         operator<<)
   {
   make f a non-member function;
   if (f needs access to non-public
       members of C)
      make f a friend of C;
   }
else if (f needs type conversions
         on its left-most argument)
   {
   make f a non-member function;
   if (f needs access to non-public
       members of C)
      make f a friend of C;
   }
else if (f can be implemented via C's
         public interface)
   make f a non-member function;
else
   make f a member function of C; 


So my question is: What now determines a member function? By the sound of this, nearly everything could be a friend function.

Ok, so I understand a list of public interface functions can consist of the virtual functions and any friend or non member function. Also such things as operator+ and similar need to be member functions, but operator+= is a non member friend function implemented in terms of operator+.

Then I thought about private functions, I guess they can remain a member function? Is there any other way of hiding them otherwise?

Another question: Would one gather up all these friend functions and put them into their own class / struct? I gather that taking the functions out of the original class improves it's flexibility and /or encapsulation, so it looks like there is more to it than moving functions from one class to another. Or is it better to have them in their own namespace as standalone functions?

Thanks in advance for any help :+)
closed account (48T7M4Gy)
It appears the article was written 15 years ago and seems to go on a with a huge amount of waffle, so be careful.

Stroustrup is the authority and he gets his message across much more clearly. What does he say about this in his latest works?
Yeah, the article is old, but that might not mean it's bad. :+)

Meyers does have a habit of turning ones thoughts of "I thought I knew that" on it's head.

I guess his whole point was about improving the flexibility encapsulation of classes by taking functions out of them. Which is apparently what happens in the STL, so it sounds good to me.

Stroustrup has a brief paragraph about friend functions on his home page, couldn't really find much elsewhere.

I did find this though:

http://www.gotw.ca/gotw/084.htm


Will have to ruminate on that a bit.

It's late at this end, I might not reply until tmrw :+)

What now determines a member function?
Well, a member function gets implicitely the this pointer. It does not make sense to write a friend function that gets it explicitely, which would basically a fake member function.

Would one gather up all these friend functions and put them into their own class / struct?
You are not free to put [the prototype of] a friend function wherever you want.
closed account (48T7M4Gy)
I'm not saying the article is bad just because it is old. However 15 years ago the world was different and there were many paradigms around. One of the best was Eiffel with design by contract. But Eiffel, although it is smart for a lot of reasons, is not mainstream.

The article goes on and on about something that is simple and really doesn't have to be so many pages of waffle.

Encapsulation and data hiding are still being taught as an underlying principle of good software engineering in the object oriented arena.

friends and operator overloading are complete anathema to Java and don't exist which is why I like C++. Stroustrup would be hard to overturn on his rationale for having those which he makes very clear. (I'll now get jumped on now by the C++ police here LOL).

The reason I like operator overloading is I can add, multiply, invert whatever, matrices completely comfortably and intuitively with operator overloading, something we can't do in Java. (I've forgotten what C# does on this.)
:)

Yeah, the article is old, but that might not mean it's bad. :+)

Considering that nothing that article talks about has changed at all, I'd say it's still pretty relevant.

He did start with the punchline: "If you're writing a function that can be implemented as either a member or as a non-friend non-member, you should prefer to implement it as a non-member function."


So my question is: What now determines a member function? By the sound of this, nearly everything could be a friend function.

According to the algorithm you reproduced, a friend function would only be called for if the function were operator>> or operator<< or if the leftmost argument required type conversion(s) and also needed access to non-public members.

The answers here may provide elucidation:
http://stackoverflow.com/questions/1692084/how-non-member-functions-improve-encapsulation
closed account (48T7M4Gy)
The important points to take away from Meyers's advice are:

Design classes to have clean, stable public interfaces separate from their private implementation;
Only make functions members or friends when they really need to access the implementation;
Only make functions friends when they can't be members.


Thanks cire, you've done well, my point exactly and no wombats fuss and waffle - agreed there's nothing new.
Stroustrup is the authority and he gets his message across much more clearly. What does he say about this in his latest works?


His latest/current work is the C++ Core Guidelines https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md

Relevant rule is C.4 "Make a function a member only if it needs direct access to the representation of a class": https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-c4-make-a-function-a-member-only-if-it-needs-direct-access-to-the-representation-of-a-class

There is also a "No long-distance friendship" in the "unclassified proto-rules" section, he didn't get to that yet.

Personally, I love using inline friend functions to reduce the visibility of overloaded operators, even if they don't need access to implementation (inline friends are only accessible via ADL), but it's a bit too obscure to write about in any public guide.
Last edited on
closed account (48T7M4Gy)
His latest/current work is the C++ Core Guidelines

Great reference thanks Cubbi. Looks like another best-seller from the master in the making. (Obviously will take more than a few minutes to digest. LOL)
Thanks everyone for their replies, I read through and digested the gotw#84 article I eventually found, and also Cubbi's and cire's references - everything is much clearer now.

The CppCoreGuidelines is awesome, hopefully some of that will make it into the standard soon.

Another thing is the proposal n3407 "Decimal Floating Point", I am not sure it will make C++17, as it seems to be lacking wording for the standard.

Cheers :+)
The CppCoreGuidelines is awesome, hopefully some of that will make it into the standard soon.

That is not its goal, although elements of the guidelines support library will be proposed for standardization.

Another thing is the proposal n3407 "Decimal Floating Point"

Its second revision, n3871, was presented at Issaquah last year, and is still on the numerics study group's agenda. It was discussed in Kona last month some more, and the last note from the discussion was "we need to more thoroughly explore what needs/could be done".. so it's in progress, but certainly not for the C++17 target. Maybe for the Numerics TS. Meanwhile, there are decimal floating-point libraries from IBM (which supports them in hardware) and I believe Intel
Last edited on
Thanks Cubbi for your reply,

From your hint, I discovered that g++ already supports exact decimals as an extension, so I will use that.

It is great to know that this stuff is on it's way to being standardised. :+)

Regards



Topic archived. No new replies allowed.