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
    If you don't know, then you don't need `friend`. – Cody Gray Jan 13 '12 at 12:04
  • 2
    There are practical examples in a question you linked. – Rafał Rawicki Jan 13 '12 at 12:07
  • Yes there are some practical examples like it can be used to test, but how far it is usable in client-side ?? –  Jan 13 '12 at 12:15
  • 2
    It's usable just as far as anything else is. I don't understand what you're asking. The other question covers cases where it might be useful. But again, the important general principle is that you don't need it unless you need it. You'll know when that time comes. – Cody Gray Jan 13 '12 at 12:21

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
  • 245,575
  • 61
  • 446
  • 609
  • 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 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 < – 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
  • 242,813
  • 27
  • 432
  • 630
  • +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 < – 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,024
  • 4
  • 33
  • 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 < – 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 < – Lol4t0 Jan 13 '12 at 12:22