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?

Falcon
  • 19,308
nikhil
  • 671
  • 3
  • 8
  • 15
  • @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 04 '11 at 18:56
  • 1
    see: http://programmers.stackexchange.com/questions/99589/what-is-friend-keyword-used-for/99595#99595 – Martin York Sep 04 '11 at 19:58
  • 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. – thomasrutter Aug 20 '21 at 07:13

8 Answers8

18

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.

DeadMG
  • 36,902
  • +1 for Friend functions are no different to member functions in terms of encapsulation. This only true for public member functions though. – TheFogger Sep 04 '11 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 04 '11 at 12:02
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.

kevin cline
  • 33,670
  • 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 05 '11 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. – kevin cline Sep 05 '11 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 – Emilio Garavaglia Jul 26 '15 at 07: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 '15 at 14:29
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.

fredoverflow
  • 6,874
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.)

Emilio Garavaglia
  • 4,299
  • 1
  • 22
  • 23
  • 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. – Konrad Rudolph Sep 05 '11 at 20:15
  • @Konrad: zealots are is superiorly unlimited set. There is always a zealot more zealot than a given zealot. – Emilio Garavaglia Sep 06 '11 at 06:54
  • I have to say I upvoted because I really liked that last paragraph. Makes a lot of sense. – julealgon Apr 09 '15 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 06 '21 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! – Emilio Garavaglia Apr 06 '21 at 14:57
  • @EmilioGaravaglia Saying a person doesn't use C++ because they are OOP Zealots doesn't make sense, as C++ was specifically designed to support OO programming. Sure, it can support far more, but your indications that these "OO Zealots" don't use C++ is just unfounded, and inflammatory. Look up the "no true Scotsman" fallacy. https://en.wikipedia.org/wiki/No_true_Scotsman I'm an OO programmer, and I use C++ – Edwin Buck Apr 06 '21 at 15:44
  • @EdwinBuck: "Saying a person doesn't use C++ because they are OOP Zealots doesn't make sense": I agree. In fact, I didn't said that. It is a metaphorical paradox. P.S. It seem you consider yourself somehow touched by the idea of being an OOP Zealot. That's not what I meant, And for the very few thing you said about yourself, you are not. – Emilio Garavaglia Apr 07 '21 at 18:54
  • "OOP Zealots don't use C++" seems like a pretty clear statement, one that (if treated as a statement of truth) would take all of the OOP Zealots out of the C++ user community. The two zen diagram circles of "OOP Zealots" and "C++ users" wouldn't overlap. If they did, you'd have an OOP Zealot that uses C++. There's not paradox, your statement is just a form of "No true Scotsman" of which you only need one example to prove it wrong. And there are plenty of C++ programmers that are OOP Zealots (by whatever definition you use for Zealot). – Edwin Buck Apr 07 '21 at 18:59
  • @EdwinBuck: OK: you don't want to understand even after explanations. Be happy with your religion, an let me be happy with mine. – Emilio Garavaglia Apr 08 '21 at 19:04
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++.

J.K.
  • 13,083
  • 1
  • 41
  • 56
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.

Gnawme
  • 1,333
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.

anon
  • 1,474
-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.

tp1
  • 1,902
  • 11
  • 10