Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ implementing friend/inline functions

I can't seem to find the answer to this newbie question. If I have a class // Header file (.h)

Class X {
public:
  friend bool operator==(const X&, const X&);
  inline size_type rows() const;
};

etc... when I go to implement the .cpp file of X, should I include the words inline & friend in the function names in the .cpp file. ie, should I implement my file similar to the below

// CPP file (.cpp)
#include "X.h"
friend bool operator==(const X&, const X&) {
  //implementation goes here
  //return true/false
}

inline size_type rows() const {
  return r;
}

or should I not include these i.e. like below

#include "X.h"
bool operator==(const X&, const X&) { ... }

size_type rows() const { ... }
like image 832
theAir Avatar asked Aug 22 '11 12:08

theAir


People also ask

Can a friend function be inline?

Friend functions can be defined (given a function body) inside class declarations. These functions are inline functions.

What is friend function how it is implemented in C++?

A friend function in C++ is defined as a function that can access private, protected and public members of a class. The friend function is declared using the friend keyword inside the body of the class. Friend Function Syntax: class className { ... .. ... friend returnType functionName(arguments); ... .. ... }

What are the rules of implementing friend function?

There are some points to remember while implementing friend functions in our program: A friend function can be declared in the private or public section of the class. It can be called like a normal function without using the object. A friend function is not in the scope of the class, of which it is a friend.

Is there friend function in C?

Friend class and function in C++ A friend class can access both private and protected members of the class in which it has been declared as friend.


2 Answers

No, you shouldn't, i.e. the 2nd version is correct.

friend can only be used within a class definition (it has no meaning outside of it), and the compiler looks for the function signature to find the definition of the friend function declared within your class X.

inline is used in header files (although, I guess, technically it is possible to use it in a cpp file too, just it makes no sense there). And note that inline makes sense only if you actually define the function right there - it can have no effect if you provide the function definition separately, in a cpp file.

The point of inline is to hint the compiler that the function in question can be inlined (it is no guarantee, though - the compiler is free to decide whether it inlines that function or not). If the function is inlined, any calls to it are replaced by a copy of the function body. This is practically always done for performance benefits, to save the costs of function calls, at the expense of potentially increasing program size. Now, if we want to inline a function, we want it to be inlined all over the place, not only within a single compilation unit; this is why it makes little sense to use the inline keyword inside an implementation file.

like image 105
Péter Török Avatar answered Nov 02 '22 07:11

Péter Török


When defining friend functions you can use one of two different options:

Define the friend function inside the class definition

namespace Test {
class test {
   int priv;
   friend void foo( test const & t ) { std::cout << t.priv << std::endl; }
};
}

Define them in the enclosing namespace:

namespace Test {
class test {
   int priv;
   friend void foo( test const & t );
};
void foo( test const & t ) {
   std::cout << t.priv << std::endl;
}
}

But note that there are differences regarding lookup. In particular, the first case is more restrictive (and thus should be preferred) as only ADL (Argument Dependent --aka Koening-- Lookup) will find it, while in the second case the function will be considered whenever that namespace is considered.

That is, for the compiler to consider the first function as an overload, the argument at the place of call must be a test, while in the second case it will be considered whenever the identifier matches, and might be considered as a valid option if the argument is convertible to test.

like image 4
David Rodríguez - dribeas Avatar answered Nov 02 '22 07:11

David Rodríguez - dribeas