Friend Functions in C++ Unveiled - CSU1287 - Shoolini U

Friend Functions

Friend Functions

Friend functions are a feature of C++ that allows non-member functions to access private and protected members of a class. They are a powerful tool for extending the functionality of classes and implementing certain design patterns. Friend functions are declared within the class definition, but are not members of the class.

In C++, functions that are not members of a class can only access the public members of that class. However, sometimes it is necessary for a function to access the private and protected members of a class. In these cases, you can declare the function as a friend function of the class. This allows the function to access the private and protected members of the class, even though it is not a member of the class itself.

Here's an example of a class that uses a friend function:

class Rectangle {
public:
  Rectangle(int l, int w) : length(l), width(w) {}
  friend int area(const Rectangle& rect);
private:
  int length;
  int width;
};

int area(const Rectangle& rect) {
  return rect.length * rect.width;
}

In this example, the Rectangle class has a friend function named area(). The area() function takes a const reference to a Rectangle object as an argument and returns the area of the rectangle. The friend keyword in the class definition allows the area() function to access the private data members of the Rectangle class.

To use the friend function, you simply call it like a regular function, passing in a Rectangle object:

Rectangle rect(5, 10);
int a = area(rect); // a is now 50

Friend functions are often used in conjunction with operator overloading to provide more natural syntax and functionality for classes. For example, you can overload the << operator to print the contents of a class to an output stream:

class Point {
public:
  Point(int x, int y) : x(x), y(y) {}
  friend std::ostream& operator<<(std::ostream& os, const Point& point);
private:
  int x;
  int y;
};

std::ostream& operator<<(std::ostream& os, const Point& point) {
  os << "(" << point.x << ", " << point.y << ")";
  return os;
}

In this example, the Point class has a friend function named operator<<(). The operator<<() function takes an output stream object and a const reference to a Point object as arguments and returns the output stream object. The friend keyword in the class definition allows the operator<<() function to access the private data members of the Point class.

To use the overloaded << operator, you simply use the << operator between an output stream object and a Point object:

Point p(5, 10);
std::cout << "p = " << p << std::endl; // prints "p = (5, 10)"

Friend functions can also be used to implement certain design patterns, such as the factory method pattern. The factory method pattern is a creational pattern that allows you to create objects without specifying the exact class of object that will be created. The factory method is a static member function of a class that returns an instance of the class or one of its derived classes. By making the factory method a friend function of the class, you can ensure that it has access to the private data members of the class, while still keeping the constructor private to prevent direct instantiation of the class.

In summary, friend functions are a powerful feature of C++ that allow non-member functions to access private and protected members of a class. They are often used in conjunction with operator overloading and design patterns to provide more natural syntax and functionality for classes. By declaring a function as a friend function of a class, you can extend the functionality of the classes and implement complex algorithms that require access to private and protected members of the class.