Friend Functions and Friend Classes in C++
In C++, encapsulation is one of the important features of object-oriented programming, allowing us to combine data and methods to form a class. To protect the private data within a class, C++ provides an access control mechanism. However, sometimes we need to allow certain functions or other classes to access these private or protected data, which is the concept of “friend”.
Friend Functions
What is a friend function?
A friend function is a normal non-member function that can access the private and protected members of a class. This means that even though this function does not belong to the class, it can still directly manipulate its internal data.
How to declare a friend function?
To define a friend function, we can use the <span>friend</span>
keyword in your class declaration. For example:
#include <iostream>
using namespace std;
class Box {
private:
double width;
public:
Box(double w) : width(w) {}
// Declare friend function
friend void printWidth(Box box);
};
// Implement friend function
void printWidth(Box box) {
cout << "Width of box: " << box.width << endl;
}
int main() {
Box box(10.0);
// Call friend function
printWidth(box); // Output: Width of box: 10
return 0;
}
Code Explanation
- We created a
<span>Box</span>
class that contains a private member<span>width</span>
. - Using the
<span>friend</span>
keyword, we declared a non-member function named<span>printWidth</span>
that can access the private members of the<span>Box</span>
class. - In the implementation, although
<span>printWidth</span>
is not a member of the<span>Box</span>
class, we are able to directly access and print its width.
Friend Classes
What is a friend class?
If an entire class is designated as a friend of another class, then all methods of that class can access the private and protected members of the other class. This is known as a “Friend Class”.
How to declare a friend class?
You simply use the <span>friend</span>
keyword in the class you want to grant privileges to, for example:
#include <iostream>
using namespace std;
class Box; // Forward declaration
class Printer {
public:
void printBoxDimensions(Box& b); // Method to print box dimensions
};
class Box {
private:
double width;
public:
Box(double w) : width(w) {}
// Declare Printer as friend class
friend class Printer;
};
// Implement Printer method to print box dimensions
void Printer::printBoxDimensions(Box& b) {
cout << "The width of the box is: " << b.width << endl;
}
int main() {
Box myBox(15.0);
// Create Printer instance and print box dimensions
Printer printer;
printer.printBoxDimensions(myBox); // Output: The width of the box is: 15
return 0;
}
Code Explanation
- We created two classes:
<span>Printer</span>
and<span>Box</span>
. - In the definition, we declared
<span>Printer</span>
as a friend class, which can access all the private members of the<span>Box</span>
class. - However, due to the “caller” relationship, only the authorized class can directly monitor and influence the variables, which is why the command line output shows significant results!
Conclusion
-
Advantages: By using the friend mechanism, you can design APIs more flexibly for debugging purposes. Although putting everything in the public domain may cause confusion, this approach provides a special case that helps you locate signals and avoid dilemmas.
-
Considerations: Over-reliance on constants and friendship may lead to maintainability issues, so use it cautiously. Also, follow the principle—first consider the public interface, then decide whether to introduce the friend mechanism. In most cases, maintaining the core encapsulation concept is crucial for a reasonable and aesthetically pleasing integration of contracts.
I hope this article helps you understand the concepts related to friendship in C++.