It is not possible to declare a member function as a friend unless the complete class definition is visible. Allowing otherwise would permit arbitrary code to declare and define members of a class that the creator of that class does not intend.
class Second // complete class definition, not just a forward declaration
{
public:
void fun();
};
class First
{
friend void Second::fun();
};
A consequence of this is that First
cannot simply be a member of Second
. To accept that, the compiler needs to have visibility of the complete definition of Second
for the definition of First
to compile, but also have visibility of the complete definition of First
for the definition of Second
to compile. That is an infinitely recursive dependence, which tends to upset compilers.
The only types of class members (or variables in general actually) that can be declared with only a forward declaration are pointers or references.
So, this would work
class First;
class Second // complete class definition, not just a forward declaration
{
private:
First &fObj; // note this is a reference
public:
void fun();
Second();
~Second();
};
class First
{
friend void Second::fun();
};
Second::Second() : fObj(*(new First)) // assumes First has appropriate (not shown) constructor
{}
Second::~Second()
{
delete &fObj;
}
However, note that both the constructor and destructor of Second
also cannot be compiled unless the definition of First
is visible to the compiler beforehand. This is because it is not possible to create or destroy an instance of a class type based on only a forward declaration (i.e. the same reason as for your original problem).
Practically, I'd just declare class Second
to be a friend of First
and be done with it. After all, declaring one member function of a class as a friend asserts that member function will always be implemented to work as intended. There are very few circumstances in which it is possible to trust a single member function of a class to work as required, but not trust other member functions of the same class.