2011-09-23 45 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

這不是問題。 –