Friend Function and Friend Class in C++

Introduction to Friendship in C++

Friendship in C++ is a mechanism that allows non-member functions or other classes to access private and protected members of a class. It’s an exception to the principle of data hiding in object-oriented programming and should be used carefully.

Friend Functions

What is a Friend Function?

A friend function is a function that is not a member of a class but has access to the class’s private and protected members. Friend functions are declared inside the class definition with the keyword friend, but they are not member functions.

Declaring a Friend Function

class MyClass {
private:
    int privateMember;
    
public:
    MyClass(int val = 0) : privateMember(val) {}
    
    // Friend function declaration
    friend void displayPrivate(const MyClass& obj);
};

// Friend function definition
void displayPrivate(const MyClass& obj) {
    // Can access private members of MyClass
    cout << "Private member value: " << obj.privateMember << endl;
}

Example of a Friend Function

#include <iostream>
using namespace std;

class Box {
private:
    double length;
    double width;
    double height;
    
public:
    // Constructor
    Box(double l = 0, double w = 0, double h = 0) {
        length = l;
        width = w;
        height = h;
    }
    
    // Member function
    double volume() {
        return length * width * height;
    }
    
    // Friend function declaration
    friend void printDimensions(const Box& box);
};

// Friend function definition
void printDimensions(const Box& box) {
    // Friend function can access private members
    cout << "Box dimensions: " << box.length << " x "
         << box.width << " x " << box.height << endl;
}

int main() {
    Box myBox(10, 6, 8);
    
    // Call member function
    cout << "Volume: " << myBox.volume() << endl;
    
    // Call friend function
    printDimensions(myBox);
    
    return 0;
}

Characteristics of Friend Functions

  1. Not a member function of the class
  2. Can access private and protected members of the class
  3. Cannot be called using an object and dot operator
  4. Declared inside the class, but defined outside it
  5. Can be declared in public, private, or protected sections (access level doesn’t matter)
  6. Cannot access class members directly by name (must use object name and dot operator)
  7. Can be a member function of another class

Friend Classes

What is a Friend Class?

A friend class is a class that has access to the private and protected members of another class. When a class is declared as a friend, all of its member functions become friend functions of the class that declared it as a friend.

Declaring a Friend Class

class ClassA {
private:
    int privateData;
    
public:
    ClassA(int data = 0) : privateData(data) {}
    
    // Declaring ClassB as a friend
    friend class ClassB;
};

class ClassB {
public:
    void display(ClassA obj) {
        // Can access private members of ClassA
        cout << "ClassA's private data: " << obj.privateData << endl;
    }
    
    void modify(ClassA& obj, int newValue) {
        // Can modify private members of ClassA
        obj.privateData = newValue;
    }
};

Example of a Friend Class

#include <iostream>
using namespace std;

class Engine; // Forward declaration

class Car {
private:
    string model;
    int year;
    Engine* engine; // Will be defined later
    
public:
    Car(string m, int y) : model(m), year(y), engine(nullptr) {}
    
    void setEngine(Engine* e) {
        engine = e;
    }
    
    void displayCarInfo();
    
    // Declare Engine class as a friend
    friend class Engine;
};

class Engine {
private:
    string type;
    int horsepower;
    
public:
    Engine(string t, int hp) : type(t), horsepower(hp) {}
    
    void displayEngineInfo() {
        cout << "Engine Type: " << type << endl;
        cout << "Horsepower: " << horsepower << endl;
    }
    
    // Can access Car's private members because Engine is a friend of Car
    void installIn(Car& car) {
        car.engine = this;
        cout << "Engine installed in " << car.model << " (" << car.year << ")" << endl;
    }
};

// Need to define this after Engine class is fully defined