0

Possible Duplicate:
When should you use 'friend' in C++?

There is a detailed explanation here, but I would like to know what is the practical use of Friend function.

How I can decide when I should go with a friend function rather than a member function?

Community
  • 1
  • 1

3 Answers3

2

In most cases, friend declarations are a code-smell since it breaks encapsulation.

Developers often use friend for a quick-fix to a problem. However a good starting design or some refactoring (more often more than less) exclude the necessity for it.

EDIT:

Even in @Darhuuk's example, a friend declaration is not needed. You can have getters for the specific fields you want to print.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 1
    It is theoretically possible for it to enhance encapsulation. For example, assuming that the fields you wanted to print were not fields that you wanted to expose publically. Although I very much agree with the general principle that `friend` can often be avoided by better design. – Cody Gray - on strike Jan 13 '12 at 12:16
  • 2
    Friend functions don't break encapsulation any more than public member functions do. Both have the same level of access, and both must be declared in the class definition. – Mike Seymour Jan 13 '12 at 12:18
  • @CodyGray I **personally** find overriding `operator <<` a little "code-smellish". I'd personally prefer a "toString()" or "print()" method. But I agree `<<` is more readable. – Luchian Grigore Jan 13 '12 at 12:18
2

You would use a friend when the function needs to be a non-member, but also needs access to class members.

Common examples where you need a non-member function are:

  • An API that requires non-member functions; for example, boost::intrusive_ptr requires that you implement intrusive_add_ref() and intrusive_release() as non-member functions.
  • Overloading a binary operator where your type need to be the right-hand operand; for example operator<<(ostream&, my_type const &).
  • Overloading a binary operator where you want the left-hand side to be convertible to your type; for example, if your class is constructible from int, then 5 + my_type will work if you define a non-member operator+(my_type const&, my_type const&);, but not if you define a member my_type::operator+(my_type const &) const;.

Whether any of these needs to be friends depends on whether they can do their job using the class's public interface; for example, you could add a public print(ostream&) member that operator<< could use, and a public operator+= member that operator+ could use.

As an example of implementing operator+ in terms of operator+=:

my_type & my_type::operator+=(my_type const & rhs)
{
    // do addition here
    return *this;
}

// The first operand is passed by value, giving a modifiable copy
my_type operator+(my_type lhs, my_type const & rhs)
{
    return lhs += rhs;
}
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • +1, best answer so far I think. The last paragraph is especially helpful as it gives some practical advice how to avoid `friend` by using a better design. The `operator+=` part is a bit unclear to me, though. Doesn't it also need to access private members of the operand in most cases where `operator+` would? – Niklas B. Jan 13 '12 at 12:29
  • @NiklasBaumstark: Assignment operators (including `+=`) can only be overloaded as members; so they have access anyway. I'll add an example of implementing `operator+` in terms of that. – Mike Seymour Jan 13 '12 at 12:34
  • @MikeSeymour, only the standard version of assignment needs to be a (non-static) member function; all compound assignment operators can be non-member functions. If so, then they may need to be `friend`s with their operand(s)' class(es). – CTMacUser Apr 12 '12 at 20:55
  • Implementing `op` in terms of `op=` necessarily disqualifies the former from being `constexpr`. If you're making a `constexpr`-enabled type, then you need to flip the dependencies between the two operators and probably make the former a `friend` (maybe defined in-class). – CTMacUser Apr 12 '12 at 21:01
  • I feel adding a `print` member function solely to avoid making `operator <<` a `friend` is a code smell, due to repeating yourself. The operator is the standard method of getting a lexical serialization of a type. (It's the same category as making all member data practically public through `get`/`set` member functions to avoid other friendships.) – CTMacUser Apr 12 '12 at 21:14
0

The simplest use case would probably be when overloading the stream output operator for a custom class.

For example, take a look at the following code (shamelessly copied from here). In this case the use of friend allows the non-class method to access the private fields of class, thus preventing the need to code several get methods (which otherwise you might not even want to create).

#include <iostream>
#include <cstring>
using namespace std;
class MyClass {
  // now private
  char name[80];
  int areacode;
  int prefix;
  int num;
public:
  MyClass(char *n, int a, int p, int nm)
  {
    strcpy(name, n);
    areacode = a;
    prefix = p;
    num = nm;
  }
  friend ostream &operator<<(ostream &stream, MyClass o);
};

ostream &operator<<(ostream &stream, MyClass o)
{
  stream << o.name << " ";
  stream << "(" << o.areacode << ") ";
  stream << o.prefix << "-" << o.num << "\n";

  return stream;
}

int main() {
  MyClass a("T", 1, 5, 1);
  MyClass b("A", 3, 5, 5);
  MyClass c("T", 2, 5, 9);

  cout << a << b << c;

  return 0;
}
AVH
  • 11,349
  • 4
  • 34
  • 43
  • I think in this example if you allow to print the value of members, you should also provide getters for them, thus making the use of `friend` superfluous. – Niklas B. Jan 13 '12 at 12:10
  • @NiklasBaumstark :) Funny you should say that, I had just edited my answer with the same argument. – Luchian Grigore Jan 13 '12 at 12:11
  • @LuchianGrigore: It seems like this argument is kind of obvious ;) – Niklas B. Jan 13 '12 at 12:12
  • @Niklas Baumstark, I think good OOP design assumes that your object has _methods_ to preform actions, but not a lot of _getters_ and _setters_ that _actually_ break encapsulation, while _serializtion_ method `operator <<` actually _hides_ realization details, but _perform action_. – Lol4t0 Jan 13 '12 at 12:15
  • @Lol4t0: If the private members in the example really are implementation details, why should they be printed out then? – Niklas B. Jan 13 '12 at 12:17
  • @Niklas Baumstark, Serialized, not printed. And then deserialized by the same class. – Lol4t0 Jan 13 '12 at 12:18
  • @Lol4t0: It can also be used to output the object to `std::cout`, for example. Also, I don't see the deserialization routine, so I don't think the example makes that use case clear. A better example would be `operator+`, I think, as it often needs to know the other operands internal representation of data to perform the addition. – Niklas B. Jan 13 '12 at 12:20
  • @Niklas Baumstark, `bost::serializtion` is done through `operator <<`, if I not mistaken. I agree, that `operator+` could be more obvious example. – Lol4t0 Jan 13 '12 at 12:22