我想定义两个类,A和B.A有一个数据成员,它是一个B类对象,并且是在类中初始化的。 A还有一个方法来检索这个B类型数据成员中的值,这个方法将在B中声明为友元方法。这是我的代码:
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;
}
不出所料,由于A类定义中B类未知,编译失败了。我试图在源中交换A和B的定义,结果更糟。有没有办法解决A和B之间的交叉引用问题?
答案 0 :(得分:3)
如果这是完整的代码,那么问题是编译器在编译类B
时不知道A
是什么。解决这个问题的一种方法是创建一个指向B的指针而不是B本身:
<强> 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;
}
答案 1 :(得分:0)
将B
类型的嵌入式成员替换为B
的指针(或引用)会改变类的工作方式,并且在复制类A
的对象时需要额外注意。< / p>
当你颠倒定义时,你不能使类A
的成员函数成为类B
的朋友,因为A
的类型在{friend
时是不完整的。 1}}声明。但是你可以让整个班级A
成为朋友。
具有类A
的嵌入成员的类B
的解决方案可能如下所示:
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;
}
所做的更改:
B
之前声明A
。使用了A
的前瞻性声明。A
设为B
的朋友。即使尚未完全定义A
,这仍然有效。使用g ++版本4.7.2进行编译(B b=B(1);
需要-std = c ++ 11)
无论如何,让一个班级A
的成员访问班级B
的私人成员是可以(而且应该)几乎总能避免的事情(参见Laszlo Papp对你帖子的评论)。