Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

friend AND inline method, what's the point ?

Tags:

I see in a header that I didn't write myself the following:

class MonitorObjectString: public MonitorObject {    // some other declarations    friend inline bool operator==(MonitorObjectString& lhs, MonitorObjectString& rhs) { return(lhs.fVal==rhs.fVal); } 

I can't understand why this method is declared as friend. I thought it would make sense if the function is defined in another place and needs to access the internal member of the class, but this is not the case here as it is inline and doesn't even need to have access to the members.

What do you think? Is the "friend" useless?

like image 718
Barth Avatar asked Dec 19 '08 14:12

Barth


People also ask

What's the point of inline function?

An inline function is one for which the compiler copies the code from the function definition directly into the code of the calling function rather than creating a separate set of instructions in memory. This eliminates call-linkage overhead and can expose significant optimization opportunities.

What is friend function and its advantage?

A friend function is used to access the non-public members of a class. It allows to generate more efficient code. It provides additional functionality which is not normally used by the class. It allows to share private class information by a non member function.

How are friend functions different from inline functions explain with example?

There's no difference. Both friend and inline are independent declaration specifiers, which can be specified in any order. There's not much point in declaring the function inline in a friend declaration though. More generally, there's no point in specifying inline in any non-defining function declaration.


1 Answers

friend inline bool operator==(MonitorObjectString& lhs, MonitorObjectString& rhs) {      return(lhs.fVal==rhs.fVal);  } 

is sometimes called friend definition, because it is a friend declaration that also defines the function. It will define the function as a non-member function of the namespace surrounding the class it appears in. Actually, the inline there is redundant: It's implicitly declared inline if it's a friend definition. Some pros and cons of it:

  • It makes the operator not visible to normal lookup. The only way you can call it is using argument dependent look-up. This will keep the namespace free of lots of operator declarations visible normally. Note that this will also disable the ability of calling it using implicit conversions to MonitorObjectString (because if both argument types do not match at the time of looking for candidates to be called, argument dependent look-up won't find the function).
  • The lookup for names starts in the scope of the class the friend definition appears in. This means that no long type-names or other names need to be written out. Just refer them as you would in a normal member function of the class.
  • As it is a friend, the function sees the internals of MonitorObjectString. But that's neither good nor bad. It depends on the situation. For example if there are functions getFVal() making the function friend is pretty pointless. Could use getFVal as-well then.

I used to like this friend definition style of operators, because they have direct access to class members, and appear within the class definition - so I could have "everything with one sight". Recently, however, I came to the conclusion that it's not always a good idea. If you can (and you should) implement the operator purely using public member functions of the class, you should make it a non-friend (and non-member) operator, defined in the same namespace of the class. It makes sure that if you change some implementation - but keep the interface of the class the same - the operator will still work and you have less cascading changes, because you know it can't access implementation details.

However, I prefer this style over writing member operators, because operator functions at namespace scope have the added features of being symmetric with their arguments: They don't treat the left side special, because both sides are just normal arguments and not object arguments that are bound to *this. If either the left or the right side is of the type of your class, the other side can be implicitly converted - regardless of whether it's left or right. For functions that are also defined without the friend definition syntax (traditionally, at namespace scope), you will have the feature of selectively including headers that make those operators available or not.

like image 165
Johannes Schaub - litb Avatar answered Nov 04 '22 03:11

Johannes Schaub - litb