问题
I want to define two classes, A and B. A has a data member which is a Class B object and is in-class initialised. A also has a method to retrieve the value in this B type data member and this method would be declared as a friend method in B. Here is my code:
class A{
public:
int getBValue();
private:
B b=B(1);
};
class B{
public:
friend int A::getBValue();
B(int i):value(i){}
private:
int value;
};
int A::getBValue(){
return b.value;
}
And unsurprisingly the compilation had failed because of unknown type B in class A definition. I had tried to swap the definitions of A and B in the source and the result was even worse. Is there a possible way to resolve this cross reference issue between A and B?
回答1:
If this is the complete code as you have it, then the problem is that the compiler doesn't know what a B
is at the time it is compiling class A
. One way to solve it is by creating a pointer to B instead of having a B itself:
A.h
#ifndef CLASS_A
#define CLASS_A
class B;
class A{
public:
int getBValue();
private:
B *b;
};
#endif
B.h
#ifndef CLASS_B
#define CLASS_B
#include "A.h"
class B{
public:
friend int A::getBValue();
B(int i):value(i){}
private:
int value;
};
#endif
A.cpp
#include "A.h"
#include "B.h"
int A::getBValue(){
return b->value;
}
回答2:
Replacing an embedded member of type B
with a pointer (or reference) to a B
changes the way your class works and needs additional care when copying objects of class A
.
When you reverse the definitions, you cannot make a member function of class A
a friend of class B
, because the type of A
is incomplete at the time of the friend
declaration. But you can make the entire class A
a friend.
A solution with class A
having an embedded member of class B
could look like this:
class A;
class B{
public:
friend class A;
B(int i):value(i){}
private:
int value;
};
class A{
public:
int getBValue();
private:
B b=B(1);
};
int A::getBValue(){
return b.value;
}
Changes made:
- Declared
B
beforeA
. A forward declaration forA
is used. - Made the class
A
a friend ofB
. This works even whenA
is not yet fully defined.
Compiles with g++ version 4.7.2 (-std=c++11 needed for B b=B(1);
)
Anyway, having a member of class A
accessing a private member of class B
is something which can (and should) almost always be avoided (see Laszlo Papp's comment on your post).
来源:https://stackoverflow.com/questions/20772688/how-to-declare-friend-method-when-class-definitions-cross-reference