2012-07-19 35 views
1

我有一個循環頭問題,它與這裏已經提到的大多數問題不同。我有兩個相互依賴的類,但是不是成員所以不要碰到編譯器無法計算類的大小的問題。所以我可以使用前向聲明來打破這個循環。使用正向引用

但是,我不希望客戶端必須包含這兩個頭才能使用我的類。標題應該是自包含的,因此用戶不需要知道這種依賴關係。有沒有辦法做到這一點?

編輯:棘手的部分是,A和B必須定義僅標題。

在頭A.hpp

#ifndef A_HPP 
#define A_HPP 

#include "B.hpp" 

struct A 
{ 
    B foo() { ... } 
}; 

#endif 

在頭B.hpp

#ifndef B_HPP 
#define B_HPP 

struct A; 

struct B 
{ 
    void bar() 
    { 
     A a = A(); 
     ... 
    } 
}; 

#endif 

在main.cpp中

#include "B.hpp" 
B().bar(); // error: 'a' uses undefined class 'A' 
+0

如果'A.hpp'包含'B.hpp',爲什麼不在'main.cpp'中包含'A.hpp'而不是'B.hpp'? – chris 2012-07-19 00:45:14

+0

'A'實際上是'B'的內部實現細節。我真的不想讓客戶知道任何事情 – thehouse 2012-07-19 00:46:53

+0

「B」應該只是一個頭部實現?否則,爲什麼頭文件中的「bar」代碼? – 2012-07-19 00:48:39

回答

3

部首B.hpp

#ifndef B_HPP 
#define B_HPP 

struct A; 

struct B 
{ 
    void bar(); 
}; 

#endif 

來源B.cpp

#include "A.hpp" 

void B::bar() 
{ 
    A a; 
} 

編輯。所以,如果你想要只有頭部實現,然後使用AndreyT解決方案。

+0

內聯屬性在此方法中丟失。 – AnT 2012-07-19 00:50:43

+0

@AndreyT過早優化是邪惡的,不是這樣嗎? – ForEveR 2012-07-19 00:52:40

+0

我應該說我希望A和B只能是標題。這是一個圖書館。 – thehouse 2012-07-19 00:54:09

2

如果兩個頭都包含需要完成另一個類型的代碼,那麼一般情況下它不可能由自包含的頭實現。

在您的具體實例(這是太簡單了,代表),你可以簡單地移動的定義,如果B::barA.hpp

inline void B::bar() 
{ 
    A a = A(); 
    ... 
} 

但是,當然,已經在A.hpp沒有按規定的B方法」看起來很優雅。

如果的B::bar「inlinedness」對你很重要,「工業」的解決方案將涉及配售B::bar定義爲附加頭文件B_aux.hpp。當包括標題,你應該包括「AUX」的人畢竟是「正常」的人都包括在內,即在main.cpp你必須

#include "A.hpp" 
#include "B.hpp" 
#include "C.hpp" 
... 
#include "B_aux.hpp" 
... 

但是,這是很明顯,不是「自足」做法。

+0

如果我將代碼移動到A.hpp並將A.hpp包含在幾個不同的.cpp文件中,是否會導致多重鏈接錯誤? – thehouse 2012-07-19 01:01:25

+0

我並不在意內聯的(虛構)性能「優勢」,所以這不是問題 – thehouse 2012-07-19 01:02:24

+0

@thehouse:如果將'B :: bar'放入'A.hpp'中,它將不會產生多個定義錯誤只要它被聲明爲「inline」即可。 – AnT 2012-07-19 01:48:33

2

只需將一個#include "A.hpp"添加到B.hpp的底部。你仍然有一個循環包含,但現在它不會傷害任何東西。

+0

我想這有點像移動課程而沒有實際移動它:p – chris 2012-07-19 01:11:05

+0

@MarkRansom我已經在內部和外部嘗試了這個內部警衛,但它並沒有幫助。同樣的錯誤。 – thehouse 2012-07-20 01:03:15

0

通常,圓形包含表示這兩種類型密切相關,這可能意味着它們是單個組件。如果是這種情況,那麼只需將兩個頭文件合併到組件的單個頭文件中,當類型聲明已經完全定義時,首先使用類型聲明,最後使用成員函數定義。