According to the C++ Primer book, the author mentioned that we can specify a class member function as a friend of another class, instead of the entire class (page 634).
Then, I tested this code:
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
I just wanted the fB()
to be friend of class A
, not the entire class B
. But the above code produced an error: 'B' : is not a class or namespace name
.
(I am using Visual C++ 2005)
Try putting the B definition before A's:
class A; // forward declaration of A needed by B
class B
{
public:
// if these require full definition of A, then put body in implementation file
void fB(A& a); // Note: no body, unlike original.
void fB2(A& a); // no body.
};
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
A
needs the full definition of B
. However, B
needs to know about A
, but does not need the full definition, so you need the forward declaration of A
.
When the compiler starts compiling the code( usually from top ) and it encounters this line:
friend void B::fB(A& a);
at this point, compiler has no idea about type info of B so it throws an error ( 'B' : is not a class or namespace name ).
by forward declaration of class B, compiler knows about type of B is Class in advance to its actual declaration with all members.
run below code after forward declaration of class B.
///////////////
class B;
class A
{
public:
friend void B::fB(A& a);
void fA(){};
};
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
Still error !!!
because forward declaration is just a declaration of an identifier for which the programmer has not yet given a complete definition. so compiler needs full definition of B before class A.
Note: class A definition dependents on type of B and also definition of B (i.e B::fB) so that forward declaration alone can not resolve, complete definition of class B needs to define before class A.
4 run this code
////////
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
Still error !!!
because class B member functions fB & fB2 having arguments of type A but compiler has no idea about type info of A so by forward declaration of class A, we can let compiler knows about type info of A. Note: class B definition only dependent on type of A not the members of A so that forward declaration of A resolve step 4.
////////////////////////
class A; // forward declaration of A needed by B
class B
{
public:
void fB(A& a);
};
class A
{
int i;
public:
friend void fA(A& a); //specifying function fA as a friend of A, fA is not member function of A
friend void B::fB(A& a); //specifying B class member function fB as a friend of A
};
// fA is Friend function of A
void fA(A& a)
{
a.i = 11; // accessing and modifying Class A private member i
cout<<a.i<<endl;
}
// B::fB should be defined after class A definition only because this member function can access Class A members
void B::fB(A& a)
{
a.i = 22; // accessing and modifying Class A private member i in Class B member function fB
cout<<a.i<<endl;
}
int main()
{
A a;
fA(a); // calling friend function of class A
B b;
b.fB(a); // calling B class member function fB, B:fB is friend of class A
return 0;
}
6 Exercise:
// Cyclic dependency
#include<iostream>
using namespace std;
class A;
class B
{
public:
void fB(A& a);
friend void A::fA(B& b); //specifying class A's member function fA as a friend of B
};
class A
{
int i;
public:
void fA(B& b);
friend void B::fB(A& a); //specifying class B's member function fB as a friend of A
};
int main()
{
return 0;
}
For this to work, the full definition of B
needs to be known before the definition of A
.
So forward declare A
, since B
doesn't need the full type, and switch the definitions around:
class A;
class B
{
public:
void fB(A& a){};
void fB2(A& a){};
};
class A
{
public:
friend void B::fB(A& a);
void fA(){}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With