Logo
Articles Compilers Libraries Books MiniBooklets Assembly C++ Linux Others Videos
Advertisement

Article by Ayman Alheraki on January 21 2026 03:04 PM

Friend Classes and Functions in Modern C++

Friend Classes and Functions in Modern C++

 

Power, Encapsulation, and Controlled Violations of Access

1. Introduction: Why friend Exists

C++ is built on strong encapsulation. By default, an object’s internals are hidden behind private and protected access specifiers.

Yet real systems often require trusted collaboration between tightly related components.

The friend mechanism exists to solve a precise problem:

Grant explicit, targeted, and non-hierarchical access to otherwise private internals.

Unlike inheritance or public APIs, friend is:

  • Explicit

  • Non-transitive

  • Non-inheritable

  • One-directional

Used correctly, it enables clean architecture. Used poorly, it destroys encapsulation.

2. What Is a friend in C++?

A friend is a function or class that is allowed to access private and protected members of another class.

Key properties:

PropertyBehavior
AccessCan access private and protected members
ScopeFriendship is not reciprocal
InheritanceFriendship is not inherited
PolymorphismFriendship is not virtual
OwnershipFriend is not a member

3. Friend Functions

3.1 Basic Syntax

Important points:

  • reveal is not a member function

  • It has full access to private members

  • Friendship is granted explicitly inside the class

3.2 Common Use Case: Operator Overloading

This is the most legitimate and common use of friend.

Reasons for using friend:

  • Operators must be symmetric

  • The operator cannot belong to both operands

  • Avoids unnecessary getters that weaken encapsulation

3.3 Stream Operators (<<, >>)

Canonical example:

This preserves encapsulation, natural syntax, and performance.

4. Friend Classes

4.1 Syntax and Semantics

Key observations:

  • The entire Engine class gains access

  • Friendship is one-directional

  • No inheritance relationship exists

4.2 Real-World Use Cases

Friend classes are justified when:

  • Two classes are conceptually inseparable

  • One class provides infrastructure for another

  • Performance prohibits public accessors

Typical examples:

  • Iterator and container implementations

  • Serializer and domain object

  • Memory allocator and object layout

  • ORM mapper and entity

5. Friendship Is Not Inheritance

This distinction is fundamental.

FeaturefriendInheritance
AccessFullControlled
RelationshipTrust-basedIs-a
PolymorphismNoYes
SubstitutabilityNoYes
TransitivityNoYes

If a design implies an is-a relationship, friend is the wrong tool.

6. Modern C++ Design Guidelines for friend

6.1 Prefer Non-Member Functions First

Modern C++ encourages non-member, non-friend functions whenever possible.

Use friend only when:

  • Accessors would expose invariants

  • Performance matters

  • Symmetric operations are required

6.2 Minimize Friendship Scope

Poor practice:

Better practice:

Rule: Grant the smallest possible friend.

6.3 friend as an Architectural Boundary

In well-designed systems, friend often marks:

  • Internal subsystems

  • Trusted infrastructure layers

  • Explicit encapsulation boundaries

This pattern appears in:

  • The C++ Standard Library

  • Compilers and toolchains

  • Game engines

  • Embedded and real-time systems

7. friend and Modern C++ Features

7.1 Templates

Function template friendship:

This is powerful but must be tightly controlled.

7.2 constexpr

Friends fully participate in compile-time evaluation.

7.3 Modules (C++20)

Modules do not change friend semantics.

Important notes:

  • Friendship does not bypass module visibility rules

  • The friend must still be visible within the module interface or implementation

Modules improve encapsulation but do not weaken access control.

8. Common Anti-Patterns

Using friend to avoid proper design Granting friendship to large subsystems Replacing interfaces with friend Treating friend as unrestricted access

9. When friend Is the Right Tool

Use friend when:

  • Two entities form a single conceptual unit

  • Zero-overhead access is required

  • Symmetric non-member operations are needed

  • Explicit trust is preferable to inheritance

Avoid friend when:

  • A public API is sufficient

  • Inheritance models the relationship

  • Access can be restricted through interfaces

10. Final Perspective

friend is not a shortcut. It is a precision tool.

In Modern C++:

  • It enables zero-cost abstractions

  • It supports correct operator design

  • It preserves encapsulation with deliberate exceptions

Strong engineers do not avoid friend. They use it deliberately and sparingly.

Advertisements

Responsive Counter
General Counter
1000737
Daily Counter
2357