朋友的功能问题

时间:2012-05-15 10:12:09

标签: c++ friend preprocessor-directive

我在使用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的空控制台项目中执行此操作

3 个答案:

答案 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前瞻性声明可以是一种选择。 循环依赖性主要是由于设计缺陷引起的。