2011-09-23 117 views
6

我有一个类(A),它必须包含两个文件,即类X和类Y.不幸的是,类Y还需要在其头文件中包含类X,因为构造函数需要一个指向类X类型的指针作为参数。头部守卫难题 - 已经在.obj问题中定义了

潜在的问题是会有链接器错误?因为A类现在有两个X类副本,一个需要使用,另一个来自Y类。这是头部守卫没用的情况。我的问题是 - 这纯粹是一个结构性问题,还是有解决方法?

我真的不希望在Y类的头文件中包含任何内容,以防我想将THAT包含在其他任何内容中,但是由于函数原型,是否有必要?

+0

这应该不是问题,只要你还没有在你的头文件中定义任何非内联函数。你能发表一些代表性的代码吗? –

+0

其实我很抱歉,我认为这个错误是来自其他地方。即使如此,这是很好的学习。所以只要头文件只包含原型,你可以包含相同的一个而没有任何问题? – SirYakalot

+1

只要将它们内联到类体中,您就可以拥有类定义以及成员函数定义,例如:class X {int foo(){return 1; }};'。这不好:class X {int foo(); }; int X :: foo(){return 1; }'。 –

回答

9

如果您具备以下条件:

X.h

#ifndef X_H__ 
#define X_H__ 

class X 
{ 
public: 
    int foo() { return 1; } 
}; 

#endif 

Y.h

#ifndef Y_H__ 
#define Y_H__ 

#include "X.h" 

class Y 
{ 
public: 
    Y(X *pX) { myval = pX->foo(); } 
    int myval; 
}; 

#endif 

something.cpp

#include "X.h" 

... 

something_else.cpp

#include "Y.h" 

... 

话,应该没问题。

但是,如果X.h,而不是看起来是这样的:

#ifndef X_H__ 
#define X_H__ 

class X 
{ 
public: 
    int foo(); 
}; 

int X::foo() { return 1; } 

#endif 

那么当你尝试链接something.cppsomething_else.cpp你的确会得到一个连接错误。 X::foo将被定义为非内联到两个单独的转换单元

+1

解决方法...?没有人想要在类中定义方法。 –

+0

@TomášZato:解决方法?有两种选择;要么在类定义中定义成员函数“inline”,要么在单独的.cpp文件中定义它。 –

+0

这只是为我节省了很多时间。但我仍然不明白为什么会出现这种情况。在我的代码中,我有一个没有类的文件X.h,只有两个辅助方法。现在我把它们放在课堂上,让它们变成静态的,它起作用。任何人都可以解释吗? –

1

您可以在Y标题中使用声明。

class X; 

由于您只使用指向X的指针,编译器不需要知道它的定义。

+0

这不是问题。 –