Inside FileTwo.h
#ifndef FILETWO
#define FILETWO
#include"FileOne.h"
class FileOne ;
class FileTwo
{
public:
int Test(FileOne One){
return (One.var1+One.var2);}
FileTwo(void);
~FileTwo(void);
};
#endif
在FileOne.h中
#ifndef FILEONE
#define FILEONE
#include"FileTwo.h"
class FileTwo ;
class FileOne
{
private:
int var1 , var2 , var3 ;
public :
friend int FileTwo::Test(FileOne One);
FileOne(){
var1= 12;var2 = 24;
}
};
#endif
在main.cpp内部
#include<iostream>
using namespace std ;
#include"FileOne.h"
#include"FileTwo.h"
int main(){
FileOne one ;
FileTo two ;
cout<<two.Test(one);
}
在编译期间,我收到以下错误
1-- error C2027: use of undefined type 'FileOne' c:\users\e543925\documents\visual studio 2005\projects\myproject\filetwo.h
2--error C2027: use of undefined type 'FileOne' c:\users\e543925\documents\visual studio 2005\projects\myproject\filetwo.h
3--error C2228: left of '.var1' must have class/struct/union c:\users\e543925\documents\visual studio 2005\projects\myproject\filetwo.h
4--error C2228: left of '.var2' must have class/struct/union c:\users\e543925\documents\visual studio 2005\projects\myproject\filetwo.h
我找到了一个解决方法,比如定义FileTwo.cpp中的Test函数。但我想知道如何在头文件中解决上述问题。
答案 0 :(得分:2)
这里的问题是您将两个文件包含在一起。当您的编译器去解析FileOne.h
时,它包含FileTwo.h
,所以它会读取它,跳过FileOne.h
(感谢包含保护;否则,您将进入无限循环)并尝试使用尚未定义的类FileOne
。
实际上,这就好像你没有在FileOne.h
中加入FileTwo.h
;您无法在One
上调用方法,因为其类型(FileOne
)尚未定义。与朋友课无关。或者还没有(稍后你会遇到这个问题)。
从您的代码中,您似乎希望使用类FileTwo
来测试FileOne
。在这种情况下,FileOne
并不需要了解FileTwo
,只是让它看看它的内脏(也就是说它是朋友)。所以你的代码可以归结为:
FileOne.h:
#ifndef FILEONE
#define FILEONE
class FileOne
{
friend class FileTwo; // This is all FileOne needs from FileTwo
private:
int var1 , var2 , var3 ;
public :
FileOne(){
var1= 12;var2 = 24;
}
};
#endif
FileTwo.h:
#ifndef FILETWO
#define FILETWO
#include"FileOne.h"
class FileTwo
{
public:
int Test(FileOne One) {
return (One.var1+One.var2);
}
FileTwo();
~FileTwo();
};
#endif
答案 1 :(得分:1)
至少在这个简单的示例中,您不需要在FileOne.h
中包含FileTwo.h
。但一般来说,循环包含意味着您的设计存在问题。
你必须让整个班级成为朋友,而不仅仅是一个方法。我也会重新考虑这种友谊,因为这引入了类之间的主要联系。你能用公共方法完成同样的工作吗?
答案 2 :(得分:1)
您拥有的是循环依赖项,可以通过使用不完整的类型声明来解决。按照目前的情况,您的代码需要在两个文件中都有完整的类型声明:
1)在FileOne.h中:friend int FileTwo::Test(FileOne One);
(你要求编译器找到FileTwo
的成员函数)
2)在FileTwo.h中:int Test(FileOne One){
return (One.var1+One.var2);}
(你要求编译器找到FileOne
的一些成员变量)
您必须在至少一个文件(class FileOne;
class FileTwo;
)中使用不完整的类型声明。您已经尝试这样做,但使用#include
指令会破坏它。您有两种选择:
一个是使FileTwo
成为整个班级的FileOne
的朋友,因为使用不完整的类型是允许的。删除#include "FileTwo.h"
。
你自己已经找到的另一个:
我找到了一个解决方法,比如在FileTwo.cpp中定义Test函数。
在这种情况下从FileTwo.h中删除#include "FileOne.h"
。
答案 3 :(得分:1)
您的朋友声明没问题,您遇到的问题是circular include
。您可以通过将一个类实现放入cpp文件来打破循环包含。
例如,将FileTwo类分解为FileTwo.h和FileTwo.cpp应该可以解决您的问题。或者,声明friend FileTwo;
然后一个前向声明就足够了:
FileOne.h
#ifndef FILEONE
#define FILEONE
class FileTwo;
class FileOne
{
private:
int var1 , var2 , var3 ;
public :
friend FileTwo;
FileOne(){
var1= 12;var2 = 24;
}
};
#endif
FileTwo.h
#ifndef FILETWO
#define FILETWO
#include "FileOne.h"
class FileTwo
{
public:
inline int Test(FileOne One)
{
return (One.var1+One.var2);
}
FileTwo(void){}
~FileTwo(void){}
};
#endif