Friendly Functions
The principle of encapsulation prohibits a member function of one class from accessing private data of another class. The concept of friendly function offers an interesting solution, in the form of a compromise between formal encapsulation of private and public data. When defining a class, it is possible to declare that one or more functions (outside the class) are "friends"; such a declaration of friendship then allows them to access private data, just like any member function.
Independent function
Friend to a class
#include <iostream>using namespace std ;class Point {int x, y ;public :Point (int abs=0, int ord=0) // constructor ("inline"){x=abs ; y=ord ;}friend int coincide(Point, Point) ; //statement friend function (independent) named coincide};/* coincide definition*/int coincide (Point p, Point q) {if ((p.x == q.x) && (p.y == q.y)) return 1 ;else return 0 ;}int main() {Point a(1,0), b(1), c ;if (coincide(a,b)) cout << "a coincide with b \n" ;else cout << "a and b are different \n" ;if (coincide(a,c)) cout << "a coincide with c \n" ;else cout << "a and c are different \n" ;return 0;}// -----------------------------Output Code-----------------------------------------// a coincide with b// a and c are different
An independent function that is a friend to a class can be summarized by the following:
class Point{int coincide (Point ..., Point ...)// private part { // we have access here to private members of any Point type object }// public partfriend int coincide (Point, Point) ;.....} ;
Although it is placed here in the public Point part, the friendship statement can appear anywhere in the class.
Class member function and friend to another class
In this case, specify in the declaration of friendship, the class to which the function concerned belongs, with the resolution operator (::).
class A{//private part//public partfriend int B::f(char, A);}class B{int f(char, A);}int B::f (char ..., A ...){// we have access here to private members of any type A object}
Functions friends to several Classes
The same function (independent or member function) may be the subject of declaration of friendship in different classes. Here's an example of a function to two classes A and B:
class A {//private part//public partfriend void f(A, B);}class B {// private part// public partfriend void f(A,B)}void f(A ..., B ...){// we have access here to private members of any type A or B object}
All the functions of a class are friends to another class
You can make as many declarations of friendship as there are functions involved. To say that all class B functions are class A friends, the statement will be placed in class A.
Example
- using a function to determine the product of a vector (Vect class object) by a matrix (Matrix class object). For
simplicity, we have limited member functions to:- a constructor for Vect and Matrix;- a display function displaying for Matrix.
- Two solutions based on the use of a friendly function called prod are provided:
- prod is independent and friend to both Vect and Matrix classes;
- prod is a member of Matrix and friend to the Vect class.
Case: Independent Friend Function
#include <iostream>using namespace std ;class Matrix ; // to be able to compile the statement of Vectclass Vect {double v[3] ; // 3-component vectorpublic :Vect(double v1=0, double v2=0, double v3=0) // constructor{ v[0] = v1 ; v[1]=v2 ; v[2]=v3 ;}friend Vect prod (Matrix, Vect) ; // prod is an Independent friend functionvoid display (){int i ;for (i=0 ; i<3 ; i++) cout << v[i] << " " ;cout << "\n" ;}} ;class Matrix {double mat[3][3] ; // matrix 3×3public :Matrix (double t[3][3]) // constructor, from 3×3 array{int i, j ;for (i=0 ; i<3 ; i++)for (j=0 ; j<3 ; j++) mat[i][j] = t[i][j] ;}friend Vect prod(Matrix, Vect) ; // prod is an Independent friend function};/ ********** prod() function *****************/Vect prod(Matrix m, Vect x) {int i, j ;double som ;Vect res ; // for the result of the productfor (i=0 ; i<3 ; i++){for (j=0, som=0 ; j<3 ; j++)som += m.mat[i][j] * x.v[j] ;res.v[i] = som ;}return res ;}int main() {Vect w(1,2,3) ;Vect res ;double tb[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ;Matrix a = tb ;res = prod(a, w) ;res.display() ;return 0;}// --------------------------Code Output----------------------------------------------------------// 14 32 50
Case: Member Function, Friend to a class
#include <iostream>using namespace std ;// / ********* Matrix class************/class Vect ; // to be able to compileclass Matrix {double mat[3][3] ; // matrice 3×3public :Matrix (double t[3][3]) // constructor, from 3×3 array{int i, j ;for (i=0 ; i<3 ; i++)for (j=0 ; j<3 ; j++) mat[i][j] = t[i][j] ;}Vect prod(Vect) ; // prod is now a member function} ;// / ********* Vect class**************/class Vect {double v[3] ; // 3-component vectorpublic :Vect(double v1=0, double v2=0, double v3=0) // constructor{v[0] = v1 ; v[1]=v2 ; v[2]=v3 ; }friend Vect Matrix::prod(Vect) ; // prod is a friend functionvoid display (){int i ;for (i=0 ; i<3 ; i++) cout << v[i] << " " ;cout << "\n" ;}} ;// / ********* prod() function definition ************/Vect Matrix::prod(Vect x){int i, j ;double som ;Vect res ; // for the result of the productfor (i=0 ; i<3 ; i++){ for (j=0, som=0 ; j<3 ; j++)som += mat[i][j] * x.v[j] ;res.v[i] = som ;}return res ;}int main() {Vect w(1,2,3) ;Vect res ;double tb[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ;Matrix a = tb ;res = a.prod(w) ;res.display() ;}
Use of classes with friendly functions
Classes will be compiled separately. Their use will be from an object module containing their member functions and a header file containing their statement. It is always possible to group several classes in the same object module and possibly in the same header file.
In any case, this compilation of classes made it possible to ensure reuse.
These possibilities are not changed when using class-based friendly functions (apart from any class declarations necessary for their use). If it is an independent functions, it must be seen that if one knows how to make it a separate object module, we risk of seeing the user of the class violate the principle of encapsulation.
The user of a class with a friendly function may still not be incorporated the friend function into the privilege editing and provide herself with another header function, and then access private data.