In C++, friend declarations are a mechanism that allows certain external functions or classes to access the private and protected members of the current class. Friend declarations can be placed in the public or private section of a class, but their effect remains consistent regardless of the declaration location. Specifically, the access level of friends is not influenced by whether they are declared in the public or private section. The key role of friends is to break encapsulation, enabling specific external functions or classes to directly access the internal members of the class.
Public vs Private Friends
Although the accessibility of friends is not affected by their declaration location (public or private section), the placement of friend declarations often reflects the designer's intent and enhances code readability.
-
Public Section Declaration: Declaring friend functions in the public section typically indicates that these friend relationships are important for understanding the class's external interface. For example, if a class represents a complex number, it may declare certain global functions (such as addition and multiplication operators) as friends to allow these functions direct access to private member variables.
cppclass Complex { public: friend Complex operator+(const Complex& c1, const Complex& c2); friend Complex operator*(const Complex& c1, const Complex& c2); private: double real, imag; }; -
Private Section Declaration: Although less common, declaring friends in the private section can enhance code encapsulation and security. This indicates that these friend relationships are private implementation details of the class, which ordinary users do not need to concern themselves with. This approach reduces the complexity of the class's public interface.
cppclass Widget { public: // ... public interface ... private: friend class WidgetHelper; // Only WidgetHelper can access Widget's private parts int data; };
Example: Using Friends
The following is an example using a friend function that demonstrates how to allow external functions to access the private data of a class.
cpp#include <iostream> class Box { private: double width; public: Box(): width(0) {} friend void printWidth(const Box& b); }; void printWidth(const Box& b) { std::cout << "Width of box: " << b.width << std::endl; } int main() { Box box; printWidth(box); // Correct, because printWidth is a friend of Box return 0; }
In this example, even though the printWidth function attempts to access the private member width of the Box class, it is permitted because printWidth is declared as a friend of Box. This demonstrates the powerful encapsulation-breaking capability of friends.