我在使用C ++中的朋友函数时遇到了一些困难,但我怀疑这更像是我对预处理程序指令和#include的问题的症状。
这是我正在做的一个愚蠢的例子。五个文件:bobby.h,bobby.cpp,billy.h,billy.cpp和main.cpp。比利有一个名为ReceiveMoney的受保护功能。 Bobby有一个名为bank的功能,可以调用Billy的ReceiveMoney。也就是说,每当鲍比去银行时,他都会和比利分钱。
billy.h
#ifndef BILLY_H
#define BILLY_H
#include "bobby.h"
class Billy
{
friend void Bobby::Bank(int, Billy &);
public:
Billy();
protected:
void ReceiveMoney(int inc);
private:
int money;
};
#endif
billy.cpp
#include "billy.h"
Billy::Billy()
{
money = 0;
}
void Billy::ReceiveMoney(int inc)
{
money+=inc;
}
bobby.h
#ifndef BOBBY_H
#define BOBBY_H
#include "billy.h"
class Bobby
{
public:
Bobby();
void Bank(int amount, Billy & b);
protected:
int money;
};
#endif
bobby.cpp
#include "bobby.h"
Bobby::Bobby()
{
money = 0;
}
void Bobby::Bank(int amount, Billy & b)
{
b.ReceiveMoney(amount/2);
}
的main.cpp
#include "billy.h"
#include "bobby.h"
int main()
{
Bobby bo;
Billy bi;
bo.Bank(150, bi);
return 0;
}
我通常会收到大量错误 错误C2653:'Bobby':不是类或命名空间名称 要么 错误C2653:'Billy':不是类或命名空间名称
我在VS0的空控制台项目中执行此操作
答案 0 :(得分:3)
您有头文件的循环依赖
billy.h
包括bobby.h
,而bobby.h
包含billy.h
显然,由于这种循环依赖,编译器无法确定类型。
最佳解决方案是重新考虑您的设计并避免循环依赖或
使用 Forward declarations 来打破循环依赖。
只需在Billy
bobby.h
即可
//#include "billy.h" <----- You don't need this include
class Billy; <----- Just Forward Declaration should suffice
你可以在这里使用前向声明,因为,声明接受/返回不完整类型的函数或方法,在这种情况下Billy
是编译器的不完整类型。
答案 1 :(得分:1)
#include中有一个循环,你不能这样做。你必须在billy.h中使用Bobby的前瞻声明。例如class Bobby;
。即使这样,您也无法声明好友功能。
唯一真正的解决方案是避免使用friend
。事实上ReceiveMoney
应该是公开的:如果Bobby代表某个帐户,那就是合乎逻辑的。
friend
上的约束使其仅用于解决类的内部行为(例如,使用集合和实现它们的节点)。
答案 2 :(得分:0)
由于循环依赖,所有类都没有完全定义。因此大量的错误。如果可能,请更改您的设计并继承或仅包含必要的内容。如前所述,Als前瞻性声明可以是一种选择。 循环依赖性主要是由于设计缺陷引起的。