views:

4741

answers:

23

I have been reading through the C++ FAQ and was curious about the friend declaration. I personally have never used it, however I am interested in exploring the language.

What is a good example of using friend?

Edit:

Reading the FAQ a bit longer I like the idea of the << >> operator overloading and adding as a friend of those classes. However I am not sure how this doesn't break encapsulation. When can these exceptions stay within the strictness that is OOP?

A: 

When implementing tree algorithms for class, the framework code the prof gave us had the tree class as a friend of the node class.

It doesn't really do any good, other than let you access a member variable without using a setting function.

Ryan Fox
+31  A: 

Firstly (IMO) don't listen to people who say friend is not useful. It IS useful. In many situations you will have objects with data or functionality that are not intended to be called publicly available. This is particularly true of large codebases with many authors who may only be superficially familiar with different areas.

There ARE alternatives to the friend specifier, but often they are cumbersome (cpp-level concrete classes/masked typedefs) or not foolproof (comments or function name conventions).

Onto the answer;

The 'friend' specifier allows the designated class access to protected data or functionality within the class making the friend statement. For example in the below code anyone may ask a child for their name, but only the mother and the child may change the name.

You can take this simple example further by considering a more complex class such as a Window. Quite likely a Window will have many function/data elements that should not be publicly accessible, but ARE needed by a related class such as a WindowManager.

class Child
{
friend class Mother;

public:

  string name( void );

protected:

  void setName( string newName );
};
Andrew Grant
As an extra note, the C++ FAQ mentions that `friend` *enhances* encapsulation. `friend` grants *selective access* to members, just like `protected` does. Any fine-grained control is better than granting public access. Other languages define selective access mechanisms too, consider C#'s `internal`. Most negative criticism around the use of `friend` is related to tighter coupling, which is generally seen as a bad thing. However, in some cases, tighter coupling is precisely what you want and `friend` gives you that power.
André Caron
+1  A: 

The tree example is a pretty good example : Having an object implemented in a few different class without having an inheritance relationship.

Maybe you could also need it to have a constructor protected and force people to use your "friend" factory.

... Ok, Well frankly you can live without it.

poulejapon
A: 

I agree with Paul. For the most part you can live without friend classes.

For the most part I've only seem them justified when overloading things such as operator<<. Even then you can easily do without them.

As a golden rule, I personally never expose the innards of my class' implementation, even if it's for display puporses only.

Cheers!

OJ
so you have no public functions either? That's got to make for an interesting design. ;) (Hint: Public member functions "expose the innards of your class' implementation" as much as friends do.)
jalf
Now you're quibbling over semantics. The public methods expose an interface which isn't tied to your innards. The innards can change without affecting the interface. Plus I never said that I don't have public functions either. I appreciate the patronising hint too.I'm struggling to see how your comment adds any value to the discussion -- especially when the thread is well over a year old.
OJ
+7  A: 

You control the access rights for members and functions using Private/Protected/Public right? so assuming the idea of each and every one of those 3 levels is clear, then it should be clear that we are missing something...

The declaration of a member/function as protected for example is pretty generic. You are saying that this function is out of reach for everyone (except for an inherited child of course). But what about exceptions? every security system lets you have some type of 'white list" right?

So friend lets you have the flexibility of having rock solid object isolation, but allows for a "loophole" to be created for things that you feel are justified.

I guess people say it is not needed because there is always a design that will do without it. I think it is similar to the discussion of global variables: You should never use them, There is always a way to do without them... but in reality, you see cases where that ends up being the (almost) most elegant way... I think this is the same case with friends.

It doesn't really do any good, other than let you access a member variable without using a setting function

well that is not exactly the way to look at it. The idea is to control WHO can access what, having or not a setting function has little to do with it.

csmba
How is `friend` a loophole? It lets *the methods listed in the class* access its private members. It still doesn't let arbitrary code access them. As such it is no different from a public member function.
jalf
friend is as close as you can get to C#/Java package-level access in C++. @jalf - what about friend classes (such as a factory class)?
Ogre Psalm33
@Ogre: What about them? You're still specifically giving *that class* and no one else access to the class' internals. You're not just leaving the gate open for arbitrary unknown code to screw with your class.
jalf
+6  A: 

The canonical example is to overload operator<<. Another common use is to allow a helper or admin class access to your internals.

Here are a couple of guidelines I heard about C++ friends. The last one is particularly memorable.

  • Your friends are not your child's friends.
  • Your child's friends are not your friends.
  • Only friends can touch your private parts.
Mark Harrison
+11  A: 

@roo: Encapsulation is not broken here because the class itself dictates who can access its private members. Encapsulation would only be broken if this could be caused from outside the class, e.g. if your operator << would proclaim “I'm a friend of class foo.”

friend replaces use of public, not use of private!

Actually, the C++ FAQ answers this already.

Konrad Rudolph
"friend replaces use of public, not use of private!", I second that
Waleed Eissa
The FQA also has something to say: http://yosefk.com/c++fqa/friend.html
Assaf Lavie
@Assaf: yes, but the FQA is, for the most part a, a lot of incoherent angry gibberish without any real value. The part on `friend` is no exception. The only real observation here is that C++ ensures encapsulation at compile-time only. And you don’t need any more words to say it. The rest is bollocks. So, in summary: this section of the FQA is not worth mentioning.
Konrad Rudolph
Most of that FQA is utter blx :)
rama-jka toti
@Konrad: "The only real observation here is that C++ ensures encapsulation at compile-time only." Do any languages ensure this at runtime? As far as I know, returning references to private members (and functions, for languages who allow pointers to functions or functions as first class objects) is allowed in C#, Java, Python and many others.
André Caron
@André: the JVM and the CLR actually *can* ensure this as far as I know. I don’t know if it’s always done but you can allegedly protect packages/assemblies against such intrusion (never done this myself though).
Konrad Rudolph
@Konrad: technically, any VM-type environment with access to the call stack can validate this fairly easily, but I think it would break a lot of existing code. For instance, I regularly declare observer callbacks as private in C# so that I can control where they are registered. I mean, if your object returns a reference to data members or member functions, it is at its own risk. I don't see *any* advantage in such limitations, only loss of the power to grant fine-grained selective access.
André Caron
@André: a privately declared delegate doesn’t break encapsulation in the slightest. It would still work just fine with an access-controlling runtime because *it’s well-defined within the type system*. What would be forbidden (and checked for) would be tries to *subvert* the type system, using either reflection or C#’s `unsafe` feature. – Just to make this clear, I’m operating on hearsay, I’ve never actually tried to use these security features. But if they weren’t in place, then a lot of .NET’s security policy framework wouldn’t make any sense.
Konrad Rudolph
@Konrad: if, by using the `unsafe` blocks, you mean the equivalent of casting to `unsigned char *` and using the member offset to access private members anyways, then I agree with you that C++ doesn't check for this at runtime. In .NET's case, I don't think any specific check to enforce encapsulation needs to be done because you won't be able to case any "pointer+offset" to an object reference anyways.
André Caron
A: 

You could adhere to the strictest and purest OOP principles and ensure that no data members for any class even have accessors so that all objects must be the only ones that can know about their data with the only way to act on them is through indirect messages, i.e., methods.

But even C# has an internal visibility keyword and Java has its default package level accessibility for some things. C++ comes actually closer to the OOP ideal by minimizinbg the compromise of visibility into a class by specifying exactly which other class and only other classes could see into it.

I don't really use C++ but if C# had friends I would that instead of the assembly-global internal modifier, which I actually use a lot. It doesn't really break incapsulation, because the unit of deployment in .NET is an assembly.

But then there's the InternalsVisibleToAttribute(otherAssembly) which acts like a cross-assembly friend mechanism. Microsoft uses this for visual designer assemblies.

Mark Cidade
+2  A: 

To do TDD many times I've used 'friend' keyword in C++.

Can a friend know everything about me?


Updated: I found this valuable answer about "friend" keyword from Bjarne Stroustrup site.

"Friend" is an explicit mechanism for granting access, just like membership.

popopome
A: 

To do TDD many times I've used 'friend' keyword in C++.
Can a friend know everything about me?

No, its only a one way friendship :`(

roo
+2  A: 

One specific instance where I use friend is when creating Singleton classes. The friend keyword lets me create an accessor function, which is more concise than always having a "GetInstance()" method on the class.

/////////////////////////
// Header file
class MySingleton
{
private:
    // Private c-tor for Singleton pattern
    MySingleton() {}

    friend MySingleton& GetMySingleton();
}

// Accessor function - less verbose than having a "GetInstance()"
//   static function on the class
MySingleton& GetMySingleton();


/////////////////////////
// Implementation file
MySingleton& GetMySingleton()
{
    static MySingleton theInstance;
    return theInstance;
}
Matt Dillard
This may be a matter of taste, but I don't think saving a few keystrokes justifies the use of friend here. GetMySingleton() should be a static method of the class.
Gorpik
The private c-tor would disallow a non-friend function to instantiate the MySingleton, so the friend keyword is needed here.
JBRWilkinson
A: 

With regards to operator<< and operator>> there is no good reason to make these operators friends. It is true that they should not be member functions, but they don't need to be friends, either.

The best thing to do is create public print(ostream&) and read(istream&) functions. Then, write the operator<< and operator>> in terms of those functions. This gives the added benefit of allowing you to make those functions virtual, which provides virtual serialization.

+5  A: 

Friend comes handy when you are building a container and you want to implement an iterator for that class. See here for an example for the iterator design pattern

rptony
+21  A: 

At work we use friends extensively for out testing code. It means we can provide proper encapsulation and information hiding for the main application code. But also we can have seperate test code that uses friends to inspect internal state and data for testing.

Suffice to say I wouldn't use the friend keyword as an essential component of your design.

Daemin
Cor, that's a splendid idea.
JBRWilkinson
+1  A: 

We had an interesting issue come up at a company I previously worked at where we used friend to decent affect. I worked in our framework department we created a basic engine level system over our custom OS. Internally we had a class structure:

         Game
        /    \
 TwoPlayer  SinglePlayer

All of these classes were part of the framework and maintained by our team. The games produced by the company were built on top of this framework deriving from one of Games children. The issue was that Game had interfaces to various things that SinglePlayer and TwoPlayer needed access to but that we did not want expose outside of the framework classes. The solution was to make those interfaces private and allow TwoPlayer and SinglePlayer access to them via friendship.

Truthfully this whole issue could have been resolved by a better implementation of our system but we were locked into what we had.

Ray
+4  A: 

Another common version of Andrew's example, the dreaded code-couplet

parent.addChild(child);
child.setParent(parent);

Instead of worrying if both lines are always done together and in consistent order you could make the methods private and have a friend function to enforce consistency:

class Parent;

class Object {
private:
    void setParent(Parent&);

    friend void addChild(Parent& parent, Object& child);
};

class Parent : public Object {
private:
     void addChild(Object& child);

     friend void addChild(Parent& parent, Object& child);
};

void addChild(Parent& parent, Object& child) {
    if( &parent == &child ){ 
        wetPants(); 
    }
    parent.addChild(child);
    child.setParent(parent);
}

In other words you can keep the public interfaces smaller and enforce invariants that cut across classes and objects in friend functions.

maccullt
A: 

Friends are also useful for callbacks. You could implement callbacks as static methods

class MyFoo
{
private:
    static void callback(void * data, void * clientData);
    void localCallback();
    ...
};

where callback calls localCallback internally, and the clientData has your instance in it. In my opinion,

or...

class MyFoo
{
    friend void callback(void * data, void * callData);
    void localCallback();
}

What this allows is for the friend to be a defined purely in the cpp as a c-style function, and not clutter up the class.

Similarly, a pattern I've seen very often is to put all the really private members of a class into another class, which is declared in the header, defined in the cpp, and friended. This allows the coder to hide a lot of the complexity and internal working of the class from the user of the header.

In the header:

class MyFooPrivate;
class MyFoo
{
    friend class MyFooPrivate;
public:
    MyFoo();
    // Public stuff
private:
    MyFooPrivate _private;
    // Other private members as needed
};

In the cpp,

class MyFooPrivate
{
public:
   MyFoo *owner;
   // Your complexity here
};

MyFoo::MyFoo()
{
    this->_private->owner = this;
}

It becomes easier to hide things that the downstream needn't see this way.

shash
Wouldn't interfaces be a cleaner way to achieve this? What's to stop someone looking up MyFooPrivate.h?
JBRWilkinson
Well, if you're using private and public to keep secrets, you're going to be defeated easily. By "hiding", I mean, the user of MyFoo doesn't really need to see the private members.Besides this, it's useful to maintain ABI compatibility. If you make _private a pointer, the private implementation can change as much as you want, without touching the public interface, thereby keeping ABI compatibility.
shash
+8  A: 

The friend keyword has a number of good uses. Here are the two uses immediately visible to me:

Friend Definition

Friend definition allows to define a function in class-scope, but the function will not be defined as a member function, but as a free function of the enclosing namespace, and won't be visible normally except for argument dependent lookup. That makes it especially useful for operator overloading:

namespace utils {
    class f {
    private:
        typedef int int_type;
        int_type value;

    public:
        // let's assume it doesn't only need .value, but some
        // internal stuff.
        friend f operator+(f const& a, f const& b) {
            // name resolution finds names in class-scope. 
            // int_type is visible here.
            return f(a.value + b.value);
        }

        int getValue() const { return value; }
    };
}

int main() {
    utils::f a, b;
    std::cout << (a + b).getValue(); // valid
}

Private CRTP Base Class

Sometimes, you find the need that a policy needs access to the derived class:

// possible policy used for flexible-class.
template<typename Derived>
struct Policy {
    void doSomething() {
        // casting this to Derived* requires us to see that we are a 
        // base-class of Derived.
        some_type const& t = static_cast<Derived*>(this)->getSomething();
    }
};

// note, derived privately
template<template<typename> class SomePolicy>
struct FlexibleClass : private SomePolicy<FlexibleClass> {
    // we derive privately, so the base-class wouldn't notice that, 
    // (even though it's the base itself!), so we need a friend declaration
    // to make the base a friend of us.
    friend class SomePolicy<FlexibleClass>;

    void doStuff() {
         // calls doSomething of the policy
         this->doSomething();
    }

    // will return useful information
    some_type getSomething();
};

You will find a non-contrived example for that in this answer. Another code using that is in this answer. The CRTP base casts its this pointer, to be able to access data-fields of the derived class using data-member-pointers.

Johannes Schaub - litb
+4  A: 

The short answer would be: use friend when it actually improves encapsulation. Improving readability and usability (operators << and >> are the canonical example) is also a good reason.

As for examples of improving encapsulation, classes specifically designed to work with the internals of other classes (test classes come to mind) are good candidates.

Gorpik
A: 

I'm only using the friend-keyword to unittest protected functions. Some will say that you shouldn't test protected functionality. I, however, find this very useful tool when adding new functionality.

However, I don't use the keyword in directly in the class declarations, instead I use a nifty template-hack to achive this:

template<typename T>
class FriendIdentity {
public:
  typedef T me;
};

/**
 * A class to get access to protected stuff in unittests. Don't use
 * directly, use friendMe() instead.
 */
template<class ToFriend, typename ParentClass>
class Friender: public ParentClass
{
public:
  Friender() {}
  virtual ~Friender() {}
private:
// MSVC != GCC
#ifdef _MSC_VER
  friend ToFriend;
#else
  friend class FriendIdentity<ToFriend>::me;
#endif
};

/**
 * Gives access to protected variables/functions in unittests.
 * Usage: <code>friendMe(this, someprotectedobject).someProtectedMethod();</code>
 */
template<typename Tester, typename ParentClass>
Friender<Tester, ParentClass> & 
friendMe(Tester * me, ParentClass & instance)
{
    return (Friender<Tester, ParentClass> &)(instance);
}

This enables me to do the following:

friendMe(this, someClassInstance).someProtectedFunction();

Works on GCC and MSVC atleast.

larsm
+1  A: 

edit: Reading the faq a bit longer I like the idea of the << >> operator overloading and adding as a friend of those classes, however I am not sure how this doesn't break encapsulation

How would it break encapsulation?

You break encapsulation when you allow unrestricted access to a data member. Consider the following classes:

class c1 {
public:
  int x;
};

class c2 {
public:
  int foo();
private:
  int x;
};

class c3 {
  friend int foo();
private:
  int x;
};

c1 is obviously not encapsulated. Anyone can read and modify x in it. We have no way to enforce any kind of access control.

c2 is obviously encapsulated. There is no public access to x. All you can do is call the foo function, which performs some meaningful operation on the class.

c3? Is that less encapsulated? Does it allow unrestricted access to x? Does it allow unknown functions access?

No. It allows precisely one function to access the private members of the class. Just like c2 did. And just like c2, the one function which has access is not "some random, unknown function", but "the function listed in the class definition". Just like c2, we can see, just by looking at the class definitions, a complete list of who has access.

So how exactly is this less encapsulated? The same amount of code has access to the private members of the class. And everyone who has access is listed in the class definition.

friend does not break encapsulation. It makes some Java people programmers feel uncomfortable, because when they say "OOP", they actually mean "Java". When they say "Encapsulation", they don't mean "private members must be protected from arbitrary accesses", but "a Java class where the only functions able to access private members, are class members", even though this is complete nonsense for several reasons.

First, as already shown, it is too restricting. There's no reason why friend methods shouldn't be allowed to do the same.

Second, it is not restrictive enough. Consider a fourth class:

class c4 {
public:
  int getx();
  void setx(int x);
private:
  int x;
};

This, according to aforesaid Java mentality, is perfectly encapsulated. And yet, it allows absolutely anyone to read and modify x. How does that even make sense? (hint: It doesn't)

Bottom line: Encapsulation is about being able to control which functions can access private members. It is not about precisely where the definitions of these functions are located.

jalf
A: 

Another use: friend (+ virtual inheritance) can be used to avoid deriving from a class (aka: "make a class underivable") => 1, 2

From [2]:

 class Fred;

 class FredBase {
 private:
   friend class Fred;
   FredBase() { }
 };

 class Fred : private virtual FredBase {
 public:
   ...
 };
Gian Paolo Ghilardi
+1  A: 

The creator of C++ says that isn't broking any encapsulation principle, and I will quote him:

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.

Is more than clear...

garzanti