0

我在使用 C++ 中的友元函数时遇到了一些困难,但我怀疑这更多是我在使用预处理器指令和#include 时遇到的问题的症状。

这是我正在做的一个愚蠢的例子。五个文件:bobby.h、bobby.cpp、billy.h、billy.cpp 和 main.cpp。Billy 有一个名为 ReceiveMoney 的受保护函数。Bobby 有一个名为 bank 的函数,它调用 Billy 的 ReceiveMoney。也就是说,每次鲍比去银行,他都会和比利分钱。

比利.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

比利.cpp

#include "billy.h"

Billy::Billy()
{
    money = 0;
}

void Billy::ReceiveMoney(int inc)
{
    money+=inc;
}

鲍比.h

#ifndef BOBBY_H
#define BOBBY_H

#include "billy.h"

class Bobby
{
public:
    Bobby();
    void Bank(int amount, Billy & b);
protected:
    int money;
};
#endif

鲍比.cpp

#include "bobby.h"

Bobby::Bobby()
{
    money = 0;
}
void Bobby::Bank(int amount, Billy & b)
{
    b.ReceiveMoney(amount/2);
}

主文件

#include "billy.h"
#include "bobby.h"

int main()
{
    Bobby bo;
    Billy bi;
    bo.Bank(150, bi);
    return 0;
}

我收到大量错误,通常是错误 C2653: 'Bobby' : is not a class or namespace name or error C2653: 'Billy' : is not a class or namespace name

我在 VS0 的一个空控制台项目中执行此操作

4

3 回答 3

3

您有头文件的循环依赖项。
billy.h包括bobby.h,而bobby.h包括billy.h
显然,由于这种循环依赖,编译器无法识别出类型。

最好的解决方案是重新考虑您的设计并避免循环依赖或
使用前向声明来打破循环依赖。

只需转发声明Billybobby.h

//#include "billy.h"     <-----  You don't need this include 
class Billy;             <-----  Just Forward Declaration should suffice

您可以在此处使用前向声明,因为声明接受/返回不完整类型的函数或方法,在这种情况下Billy是编译器的不完整类型。

于 2012-05-15T10:14:50.883 回答
1

你的#include 中有一个循环,你不能这样做。您必须在 billy.h 中使用 Bobby 的前向声明。比如class Bobby;。即使这样,您也无法声明朋友功能。

唯一真正的解决方案是避免使用friend. ReceiveMoney实际上应该是公开的:如果 Bobby 代表一个帐户之类的东西,那是合乎逻辑的。

上的约束friend使其仅对解决类的内部行为有用(例如,使用集合和实现它们的节点)。

于 2012-05-15T10:23:53.857 回答
0

由于循环依赖,没有一个类是完全定义的。因此有大量错误。如果可能的话,改变你的设计并继承或只包括必要的东西。正如 Als 所提到的,前向声明可以是一种选择。循环依赖主要是由于设计错误而产生的。

于 2012-05-15T10:24:23.557 回答