friend function

I know that friend functions can give you access to the classes private data. what im confused about is why you would want to use a friend function in the first place rather then just add it as a member function of the class. how will i know if i should use a friend function or just add it as a function member.
Last edited on
Practical use of friendship is actually quite rare in my experience, and if you find yourself using it, you probably shouldn't be.

what im confused about is why you would want to use a friend function in the first place rather then just add it as a member function of the class.


Because the function might be a member of a different class. Or it might be an operator overload that can't be a member function.

Here's one example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyInt  // a class to simulate an integer
{
private:
  int data;  // some private data that can only be accessed by members / friends

public:
  // MyInt + int:
  //  this can be a member function because MyInt is on the left side of the +
  int operator + (int v) { return data + v; }

  // int + MyInt:
  //   this can't be a member function because 'int' is on the left side
  friend int operator + (int l,MyInt r) { return l + r.data; }
};


how will i know if i should use a friend function or just add it as a function member.


If you can make it a member (and it makes sense to do so), then make it a member.

Honestly you shouldn't worry too much about it. Like I said, having to use friendship is actually quite rare.
In the case of some operators, there is absolutely no difference between declaring it as a member function or as a friend function:

1
2
3
4
5
6
class Vec
{
  int data[3];
public:
  int const &operator[](int i) const { return data[i]; }
};


is precisely the same as:

1
2
3
4
5
6
class Vec
{
  int data[3];
public:
  friend int const &operator[](Vec const &v, int i) { return v.data[i]; }
};



However, if it is not an operator, but an ordinary function, then it makes a difference in notation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Vec
{
  int data[3];
public:
  int const &subscr(int i) const { return data[i]; }
  friend int const &subscr(Vec const &v, int i) { return v.data[i]; }
};

int main()
{
  Vec v;
  v.subscr(1); // Member
  subscr(v,1); // Friend
}


In this case, if there is an established consesus, you should follow taht, otherwise let it be a matter of personal taste.


In general, there will always be a duality between these two forms, and it all comes down to a question of what is the most natural notation for the specific thing that you are creating.

As Disch points out, the only time you might not have a choice, is when you are extending somebody else's class.
Last edited on
ok thanks alot guys.
I also have a question about this ... what's the difference between the friendship and inheritance relation between the classes ? and if it's inheritance how can i access the private members ? thanks for your help...
There is a major difference between the two. If a class inherits another class, it sort of becomes the original class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class AA{
friend class CC;
public:
int getVal1(){return Value1};
void setVal1(int aval){Value1=aval;}

private:
int Value1;
};

class BB : public AA{  //this class inherits AA

};

class CC{
public:
void printVal(AA anObject){cout<<"Value == "<<anObject.Value1<<endl;}   //CC can access "Value1" variable directly
                                   // because it is a friend.  Notice an instance of AA has to be passed to it.
};

int main(){
//Inheritance
BB myObject;
myObject.setVal(5);
cout<<"Value == "<<myObject.getVal1()<<endl;

//Friendship
AA myAA;
myAA.setVal1(98);
CC myCC;
myCC.printVal(myAA);    //an instance of AA is passed to myCC.printVal function

}


As you can see, class BB does not declare anything, but since it inherited from AA, it can be accessed by the same public members.

Also, you can see that CC can access private variables for an AA instance. It is important to distinguish between a class and an instance of a class (also called an object).

Hope this clears some things up for you
Last edited on
yep it does ! thanks a lot man...
Topic archived. No new replies allowed.