Friend Class In C++
Asked Answered
P

4

9

here im not understanding the concept very well or i am right.... So lets take this "friend" class example here:

class MyClass{
friend class AnotherClass;
private:
       int secret;
}

class AnotherClass{
public:
      void getSecret(MyClass mc){
          return mc.secret;
      }
}

So Yes... in the above code it will actually work if you do it... but in general, why cant you use getters and setters all the time instead of friend class? Is the reason of friend class usage because of "tediousness"?

Pokorny answered 22/4, 2016 at 10:25 Comment(0)
C
21

friend is for when you don't want to expose getters/setters/internals to everyone, but just to a single class. So it's a tool for encapsulation.

For example, if you provided a public getSecret in MyClass, everyone could have access to that private variable even if they shouldn't know about it. This breaks encapsulation. friend is there to fix this problem, so that only those classes that need to know about secret have access to it.

As @nicomp said, "it's like giving your physical friend a key to your house but you don't know what they will do with it". So a friend class has unlimited access to all internals of the class it's friends with. This in unfortunate, but the key (no pun intended) here is to keep classes as small as possible so that this doesn't become a problem, which also would be according to the Single Responsibility Principle.

Calliope answered 22/4, 2016 at 10:29 Comment(1)
Oops I figured out I'm too lazy to edit it into my answer, but if anyone cares, it's SFML's Drawable class, which uses friend pretty cleverly.Calliope
D
3

A public getter or setter permits anybody access. They have some uses, notably for maintaining class invariants when some property is changed, but a getter / setter pair that look like the following code are no better than public member variables for constraining access:

class A {
 public:
  int getX() const { return x; };
  void setX(int x_) { x = x_; };
 private:
  int x;
};

The getX() and setX() functions do nothing but provide access to x. Everybody can use them, so anybody can change the value of x. There's no point making it private, then.

If, instead, only some classes or functions need to be able to change x, you can make them friends of class A. This restricts the access to only those friends, rather than giving it to everybody.

As such, friend is a tool for encapsulation, permitting the encapsulation to be wider than "just my own class" (private members) or "just my class and classes that derive from it" (protected members). A friend need not be in the same class hierarchy (it need not be a class at all; functions can be friends), but it still permits you to restrict access to only those things that actually need it.

Note that, like getters and setters, it should be used sparingly. Encapsulation is a good thing, and where possible the private members of your class should remain just that – private. friend is a tool that allows you to selectively grant access, but you should always carefully consider whether that access needs to be granted, or whether the function / class that needs it would be better off as a member of your class, instead.

Dingman answered 22/4, 2016 at 10:33 Comment(2)
@MrWonderful I updated the answer to qualify my statement to explain that I am referring to constraining access when I say “no better”. Hope this helps to clarify things a bit.Dingman
I think that sounds much better (to me, anyway.) Thanks for the nod!Calliecalligraphy
C
2

Don't forget about testing and/or copying...

Friend classes / methods can be used quite successfully for checking intermediate states within class functionality.

They can also be useful for some types of copy constructors, where the class to be copied is not a direct ancestor of the target class thus precluding protected members as an option.

Calliecalligraphy answered 10/3, 2020 at 20:28 Comment(0)
U
0

Consider the following use-case that I encountered recently: I refactored some code from one class into another class. This new class had to access members from the original class but I did not want to provide this via public getters to avoid other clients messing around with these. In this case, I really welcomed the C++-friendship mechanism.

However, these use cases are very seldom (hopefully, otherwise there is probably something wrong in your SW architecture) and I try to avoid it as much as I can since it is the tightest form of coupling.

Unquestionable answered 22/4, 2016 at 10:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.