class x
{
void xx() {}
};
class y
{
friend void x::xx();
};
This results in an error like
error: friend function 'xx' is a private member of 'x'
Why can't I declare a private member function to be a friend of another class?
class x
{
void xx() {}
};
class y
{
friend void x::xx();
};
This results in an error like
error: friend function 'xx' is a private member of 'x'
Why can't I declare a private member function to be a friend of another class?
A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.
The reason is quite simple; private
members shall obey a clear and definite rule:
A member of a class can be
private
; that is, its name can be used only by members and friends of the class in which it is declared.
Allowing private members to be named in declarations inside unrelated classes would violate this rule: it enables another class to depend on an implementation detail without being explicitly allowed to. This becomes problematic, for instance, when changing a private member's name, type or signature, or removing it entirely; that's intended not to break the interface of that class.
This can be circumvented by making the entirety of x
a friend of y
:
class x {
void xx() {}
};
class y {
friend x;
};
Demo.
y
friend of x
? In your example y
wouldn't get access to private methods of x
. –
Adios x
to access private data of y
. –
Ode The idea of making x::xx
private
is supposed to be that x::xx
is an implementation detail that other classes should not be relying on. It doesn't just mean that x::xx
cannot be called by other classes, it means, or rather it should mean, that e.g. renaming x::xx
to x::xy
shouldn't break anything other than the class itself, and the class's friends.
In your case, renaming x::xx
to x::xy
would cause class y
to have an error, even though it is not a friend of x
.
A way to avoid that is to make y
a friend of x
, so that y
can access x
's private
members. It can then declare x::xx
as a friend
.
(Note: the more direct answer to the question "Why does the compiler not allow this?" is "Because the standard does not allow this.", which naturally leads to the follow-up question "Why does the standard not allow this?". I'm attempting to answer that follow-up question.)
y
a friend of x
for it to be able to befriend a member of x
? Why the detour? –
Ode x
a friend of y
. This is the obvious solution. But if x
is a huge class with lots of functions and y
is a tiny helper class, making y
and x::xx
friends can be far less invasive than making all of x
a friend. –
Handmedown © 2022 - 2024 — McMap. All rights reserved.