Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

C++ Class Members and Friends

5.00/5 (5 votes)
22 Nov 2013CPOL2 min read 9K  
This article tells us how to grant access to its non public members by the use of friend mechanism.

Introduction

This article tells us how to grant access to its non public members by the use of friend mechanism.

Friend Mechanism

  • A friend of a class X is a function or class that is not a member of X, but is granted the same access to X as the members of X
  • Functions declared with the friend specifier in a class member list are called friend functions of that class
  • Classes declared with the friend specifier in the member list of another class are called friend classes of that class.
  • A class Y must be defined before any member of Y can be declared a friend of another class.
  • We can define a function as a friend or an entire class as friend. The function can be a member of a class or declared in the global namespace. The function needs to be declared before it can be used as friend.
  • If a friend function is a member of another class,a scope resolution operator needs to be used ,for example Y::print(X\& x);
  • However a function can be defined provided function is unqualified and has namespace scope (function is not a member of function of another class or declared in another workspace) and class is non local.
  • C++
    #include <iostream> 
    #include <typeinfo> 
    #include <stdlib.h> 
    using namespace std; 
    
    class F; 
    class X; 
      
    void print2(); 
    void print1(X x1); 
    
    class Y { 
    public: 
      void print(X& x); 
    }; 
      
    class X { 
      private: 
      int a; 
      protected: 
      int c; 
      friend void Y::print(X& x); 
      friend void print1(X x); 
      friend void print2() 
      { 
          cout << "defining a friend function in the class " <<endl; 
      } 
    
    public: 
      X() : a(1), c(2) { } 
    }; 
      
    
    void print1(X x1) 
    { 
      cout << "In member function  " << __PRETTY_FUNCTION__ <<endl; 
      cout << "a is " << x1.a << endl; 
      cout << "c is " << x1.c << endl; 
    } 
      
    void Y::print(X& x) { 
      cout << "In member function  " << __PRETTY_FUNCTION__ <<endl; 
      cout << "a is " << x.a << endl; 
      cout << "c is " << x.c << endl; 
    }
    
    int main() { 
      X xobj; 
      Y yobj; 
      yobj.print(xobj); 
      print1(xobj);   
      print2();   
    } 
  • If a class F is a friend of class A,then every member function and static data member definition of class F has access to class A.
  • For using the class as a friend,in the declaration must be elaborated class name , for example friend class F
  • A friend class can be defined after it is declared as friend in other class
  • A friend cannot be declared with a storage class specifier.
  • A class cannot be defined within a friend declaration:
  • C++
    #include <iostream> 
    #include <typeinfo> 
    #include <stdlib.h> 
    
    using namespace std; 
    class F; 
    class X; 
    
    class X { 
      private: 
      int a; 
      protected: 
      int c; 
      friend class F; 
      
    public: 
      X() : a(1), c(2) { } 
    }; 
      
    class F 
    { 
    public: 
        void print(X& x) { 
          cout << "In member function  " << __PRETTY_FUNCTION__ <<endl; 
          cout << "a is " << x.a << endl; 
          cout << "c is " << x.c << endl; 
        } 
    }; 
      
    int main() { 
      X xobj; 
      F fobj; 
      fobj.print(xobj); 
    }
  • The scope of a friend class name is the first nonclass enclosing scope In the example the scope of the friend class name is class Z1 and not class
  • C++
    class Z; 
    void print3(Z &z); 
    class Z 
    { 
    public: 
      
    class Z1 
    { 
       private : 
       int z1; 
       public: 
          Z1() : z1(4){} 
          friend void print3(Z &z) 
          { 
            cout << "In member function  " << __PRETTY_FUNCTION__ <<endl; 
            //cout << "a is " << z.z2 << endl; //including this line will give compilation error 
            cout << "b is " << z.z11.z1 << endl; 
          } 
    }; 
    Z1 z11; 
    
    private : 
    int z2; 
    public: 
    Z() : z2(3){} 
    };
  • Friends of a base class are inherited by any classes derived from that base class The functionality that the friend of the base class are inherited by the derived by the base class may be compiler dependent.The g++ compiler on Linux supports this feature,while many online references suggest this inheritance does not hold.
  • C++
    class X {
      private:
      int a;
      protected:
      int c;
      friend class F;
    public:
      X() : a(1), c(2) { }
    };
    
    class X1 : private X
    {
    
    };
    
    class F
    {
    public:
        void print(X& x) {
          cout << "In member function  " << __PRETTY_FUNCTION__ <<endl;
          cout << "a is " << x.a << endl;
          cout << "c is " << x.c << endl;
        }
    
        void print(X1 & x1) {
          cout << "In member function  " << __PRETTY_FUNCTION__ <<endl;
          cout << "a is " << x1.a << endl;
          cout << "c is " << x1.c << endl;
        }
    
    };
    
    int main() {
      X xobj;
      fobj.print(xobj);
      fobj.print(x1obj);
    }
  • If a class is derived from a friend class ,then it is also a friend of the original base class.This feature may also be compiler dependent.The g++ compiler on Linux supports this feature,while many online references suggest this inheritance does not hold.
  • C++
    class X {
      private:
      int a;
      protected:
      int c;
      friend class F;
    public:
      X() : a(1), c(2) { }
    };
    
    class X1 : private X
    {
    
    };
    
    class F
    {
    public:
        void print(X& x) {
          cout << "In member function  " << __PRETTY_FUNCTION__ <<endl;
          cout << "a is " << x.a << endl;
          cout << "c is " << x.c << endl;
        }
    
        void print(X1 & x1) {
          cout << "In member function  " << __PRETTY_FUNCTION__ <<endl;
          cout << "a is " << x1.a << endl;
          cout << "c is " << x1.c << endl;
        }
    
    };
    
    int main() {
      X xobj;
      fobj.print(xobj);
      fobj.print(x1obj);
    }
  • Friendships are not transitive if A is a friend of B,and C is a friend of A,it does not imply that C is a friend of B unless explicitly specified.
  • C++
    class X {
      private:
      int a;
      protected:
      int c;
      friend class F;
    public:
      X() : a(1), c(2) { }
    };
    
    class X1 : private X
    {
    
    };
    
    class F
    {
    public:
        void print(X& x) {
          cout << "In member function  " << __PRETTY_FUNCTION__ <<endl;
          cout << "a is " << x.a << endl;
          cout << "c is " << x.c << endl;
        }
    
        void print(X1 & x1) {
          cout << "In member function  " << __PRETTY_FUNCTION__ <<endl;
          cout << "a is " << x1.a << endl;
          cout << "c is " << x1.c << endl;
        }
    
    };
    
    int main() {
      X xobj;
      fobj.print(xobj);
      fobj.print(x1obj);
    }

Code

The code used in the article can be found in Git repository https://github.com/pi19404/m19404/tree/master/CPP/t1.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)