/*
Friend Classes

Just as we have the possibility to define a friend function, we can also define 
a class as friend of another one, granting that first class access to the 
protected and private members of the second one
*/


#include <iostream>
using namespace std;

class CSquare;

class CRectangle {
      int width, height;
      public:
             
      int area ()
      {
          return (width * height);
      }
      
      void convert (CSquare a);
};

class CSquare {
      private:
              int side;
      public:
             void set_side (int a)
             {
                  side=a;
             }
      friend class CRectangle;
};

void CRectangle::convert (CSquare a) 
{
      width = a.side;
      height = a.side;
}

int main () {
    CSquare sqr;
    CRectangle rect;

    sqr.set_side(4);
    rect.convert(sqr);
    cout << rect.area();
    
    std::cin.get();
    return (0);       
}

/*
In this example, we have declared CRectangle as a friend of CSquare so that CRectangle member functions could
have access to the protected and private members of CSquare, more concretely to CSquare::side, which describes
the side width of the square.

You may also see something new at the beginning of the program: an empty declaration of class CSquare. This is
necessary because within the declaration of CRectangle we refer to CSquare (as a parameter in convert()). The
definition of CSquare is included later, so if we did not include a previous empty declaration for CSquare this class
would not be visible from within the definition of CRectangle.

Consider that friendships are not corresponded if we do not explicitly specify so. In our example, CRectangle is
considered as a friend class by CSquare, but CRectangle does not consider CSquare to be a friend, so CRectangle
can access the protected and private members of CSquare but not the reverse way. Of course, we could have
declared also CSquare as friend of CRectangle if we wanted to.
*/
