2012-05-15 71 views
0

我在使用C++编写朋友函数时遇到了一些困难,但我怀疑这更像是我对预处理器指令和#include有问题的症状。朋友功能问题

这是我正在做的一个愚蠢的例子。五个文件:bobby.h,bobby.cpp,billy.h,billy.cpp和main.cpp。比利有一个名为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:“博比”:不是类或命名空间名称 或 错误C2653:“比利”:是不是一个类或命名空间名称

我在VS0

回答

3

这样一个空控制台项目你的头文件循环依赖
billy.h包括bobby.h,而bobby.h包括billy.h
显然,由于这种循环依赖关系,编译器无法确定类型。

最好的解决办法是重新考虑你的设计,避免循环依赖或
使用Forward declarations打破循环依赖。

只是向前声明Billybobby.h

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

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

+0

嗯,我并不是全新的。我确实尝试了前向声明。行b.ReceiveMoney(金额/ 2);在bobby.cpp中导致使用未定义类型的错误'Billy' – Tim

+0

@Tim:在'bobby.cpp'中包含'billy.h'。 –

+0

谢谢你,你一直很有帮助。 – Tim

1

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

唯一真正的解决方案是避免需要friendReceiveMoney事实上应该是公开的:如果Bobby代表某个帐户,这是合乎逻辑的。

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

+0

我想要的是只有某个类可以使用的功能,并且只能在该类的某个功能中使用。我无法想象有没有办法做到这一点。 – Tim

+0

我明白你试图去做什么,但是在OO中,你通常以另一种方式来做:你公开什么需要从你自己的其他类中调用,并且你创建了一个接口,Billy可以从中获得实际提供的接口到您的代码的“客户”。您的情况下,该界面不包含ReceiveMoney。 – armel

0

由于循环依赖性,没有任何类完全定义。因此大量的错误。如果可能的话,改变你的设计,并继承或只包括必要的东西。正如Als提出的前瞻性声明可能是一种选择。 循环依赖主要是由于设计错误引起的。