27

I have an object oriented programming with c++ course this semester at college and we were learning about friend functions.

I instinctively dislike them for their ability to bypass the security that Encapsulation and Data hiding provide, I read a few articles on the internet and some people thought that it was a good idea with some legitimate uses.

What would an OOPs expert say about friend fucntions in C++? Should I just skim over it or should I learn more about it?

3
  • @all : Awesome answers and comments, This is such a great way to learn, there's no way i'd have learned about friends in such details in a textbook.
    – nikhil
    Sep 4, 2011 at 18:56
  • 1
  • In terms of "bypassing the security", they can only be declared to be friends inside the scope of the class definition, which is the same as methods really - and their ability to see private members inside the class is also the same as for methods. So it's for giving functions which aren't called in the same was as a method the ability to see inside objects of a class in the same way as a method. Aug 20, 2021 at 7:13

8 Answers 8

17

It is not always convenient to make all the functions related to a C++ class members of that class. For example, imagine an implementation of vector algebra with scalar multiplication. We want to write:

 double a;
 Vector v, w;
 w = v * a;

We can do this with a member function:

public class Vector {
 ...
 Vector operator*(double a);
}

But we would also like to write:

w = a * v

This requires a free function:

 Vector operator*(double a, Vector v)

The friend keyword was added to C++ to support this usage. The free function is part of the Vector class implementation, and should be declared in the same header and implemented in the same source file.

Similarly we may use friend to simplify the implementation of tightly coupled classes, like a collection and an iterator. Again, I would declare both classes in the same header, and implement them in the same source file.

4
  • 4
    "This requires a free function". No, it doesn't: inline Vector operator*(double a, Vector v) { return v*a; }. Canonical solution in fact.
    – MSalters
    Sep 5, 2011 at 12:31
  • 1
    @MSalters: Good point. I picked a poor example. I think your inline function is a free function by definition, but no friend declaration is required. Sep 5, 2011 at 19:11
  • 6
    @MSalters: That's valid only if * is commutative respect to a and v(x). If the vector components are generic (not necessarily scalars) you have to keep the operand order Jul 26, 2015 at 7:39
  • That's pretty theoretical. Perhaps the only common non-commutative case would be inline Vector operator*(double a, Vector v) { return -v*a; } and that still doesn't require friendship.
    – MSalters
    Jul 26, 2015 at 14:29
19

Friend functions are no different to member functions in terms of encapsulation. They can, however, offer other advantages- such as being more generic, especially where templates are concerned. In addition, some operators can only be specified as free functions, so if you want them to have member access, you must friend.

It's better to friend a single function than be forced to make something you don't want to be public. That means the whole world can use it- instead of just one function.

2
  • +1 for Friend functions are no different to member functions in terms of encapsulation. This only true for public member functions though.
    – TheFogger
    Sep 4, 2011 at 11:35
  • 1
    @TheFogger: Arguably, you could also friend a function which is also "private", such as only declared in a single TU.
    – DeadMG
    Sep 4, 2011 at 12:02
7

Does "friend" violate encapsulation?

No. It does not. "Friend" is an explicit mechanism for granting access, just like membership. You cannot (in a standard conforming program) grant yourself access to a class without modifying its source.

5

"What would an OOPs expert say ..." It mostly depends on how expert he is in C++, that -by its own specification - is not (and doesn't want to be) a language for purist.

OOP Zealots don't use C++ (they prefer Smalltalk, and like Java).

Functional programming zelots don't use C++ (they prefer LISP, and its successors)

The most of OOP experts dislike friend function simply because they want the OOP part of C++ to behave like Smalltalk. But C++ is not Smalltalk, and they cannot even understand that friend don't break encapsulation, for the very simple reason that a function cannot be friend of your class without your class wants it.

And from the "functionality" stand point, between a.fn(b) and fn(a,b) there is no difference (where fn is a friend): the involved parties are the same. Simply, one syntax may be more suitable than another: if fn is commutative regarding a and b, fn(a,b) is probably more suitable then a.fn(b) (where a looks having a "special role" that, in fact, it doesn't.)

9
  • 1
    “OOP zealots” who like Java haven’t understood OOP. Getters? Setters? No simple syntax for closures? To paraphrase Alan Kay, this isn’t how he imagined OOP. Sep 5, 2011 at 20:15
  • @Konrad: zealots are is superiorly unlimited set. There is always a zealot more zealot than a given zealot. Sep 6, 2011 at 6:54
  • I have to say I upvoted because I really liked that last paragraph. Makes a lot of sense.
    – julealgon
    Apr 9, 2015 at 18:17
  • @EmilioGaravaglia Calling someone a zealot is the same as calling them dirty, idiot, stupid, or dumb. There's no advancement of the conversation because you're too busy name calling instead of reasoning.
    – Edwin Buck
    Apr 6, 2021 at 13:36
  • @EdwinBuck: There is a technical definition for "Zealot": someone who adhere literally to a pre-established doctrine. That's not good or bad "per se". If that makes someone to feel "dirty, idiot, stupid, or dumb" it's not my problem. May be they have to reconsider their doctrine. Or may be they are right, and I am wrong. Who knows! Apr 6, 2021 at 14:57
4

If you're passionate about what you do, you would be learning everything about C++. Learn what they're used for, how to use them, and then - and only then - decide not to use them. At the very least, you'll be prepared when reading someone else's code that uses this facet of C++.

2

The C++ FAQ is succinct:

Use a member when you can, and a friend when you have to.

The FAQ presents one of the more useful ways of thinking about friendship:

Many people think of a friend function as something outside the class. Instead, try thinking of a friend function as part of the class's public interface. A friend function in the class declaration doesn't violate encapsulation any more than a public member function violates encapsulation: both have exactly the same authority with respect to accessing the class's non-public parts.

Perhaps the most common use of friend functions is overloading << for I/O.

0

Friend functions are best used for user-defined operator definitions. They are useful in other situations, but if you find yourself specifying friend classes frequently then you may be on a design detour (just a good self-check to use while writing code).

Do be careful about the "security" statement in the original question. Access modifiers are there to prevent you from writing bad code on accident, just like the compiler in a way. Access modifiers limit the interface, and serve to communicate what functions are important to use the class (public and protected), and which ones were created as part of making the class prettier for the maintainers (private). Modifiers do not constitute security in that there are many ways to get at private data. For example, get a pointer to the class and its size, and go fishing.

-2

C++ friend functions are closely related to the following functionality:

  1. free functions
  2. static functions
  3. friend functions

This means that they do not have this-pointer and thus are outside of the class/object. On the other hand, they often take parameters that make them again belong to the class. Here's some example which clarifies the link:

class B;
class A {
public:
    friend void f(A &a, B &b);
private:
    int m_a;
};
class B {
public:
   friend void f(A &a, B &b);
private:
   int m_b;
};
void f(A &a, B &b) { /* uses both A's and B's private data */ }

The only difference between static functions and friend functions is that a friend function can use several classes.

Using friend mechanism in c++ requires programmers that have about 10-15 years experience with the c++ way of programming, and thus initially you should avoid it. It's advanced feature.

6
  • 7
    And you derived 10-15 years how?
    – DeadMG
    Sep 4, 2011 at 10:26
  • 10-15 years comes from the time when it first become actually necessary.
    – tp1
    Sep 4, 2011 at 12:54
  • 3
    So you arbitrarily made up a number, then.
    – DeadMG
    Sep 4, 2011 at 15:42
  • 3
    -1: "You should avoid it." Every feature of C++ was created to solve a problem. When that problem arises, use the appropriate feature. Sep 4, 2011 at 19:18
  • Thanks for the -1. There was a reason for that comment. Guess it's just difficult concept that not all the features are suitable for beginners.
    – tp1
    Sep 5, 2011 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.