2013-01-21 16 views
2

這個讓我撓腦袋太久了。爲什麼這個cpp在其相應的頭文件沒有看到函數?

我有一個頭test.h以下:

inline void anything(){ 
std::cout<<" anything "<<ii; 
} 

然後,我有啊,其包括test.h:

class Fooness{ 
public: 
Fooness(){ 
    anything(); //compiler reports "use of undeclared identifier" 
    }; 
}; 

但是,如果我只需要移動功能定義a.cpp:

Fooness::Fooness(){ 
anything(); 
} 

它的工作原理。 a.cpp包含test.h,其中包含a.h.爲什麼anything()只能在a.cpp中看不到a.h?

+3

is.h包含在test.h中? – leemes

+0

取消我的評論,leemes已經全部結束了。= P – WhozCraig

+0

@ lemes是的。 – johnbakers

回答

2

當您在評論中指出,就包含在test.ha.h反之亦然。由於循環依賴,也被稱爲交叉包含,這引入錯誤作爲「未定義」的函數和類。

在你的情況下,當.cpp文件包括test.h,它首先包括a.h然後定義函數anything();,這顯然不是你想要的,處理a.h時,因爲anything()是不確定的。

你的代碼擴展到與此類似,編制包括test.ha.h前)的單位,其本身包括a.h任何事情之前的時候:

/* INCLUDED FROM a.h */ 
class Fooness{ 
public: 
Fooness(){ 
    anything(); 
    }; 
}; 

inline void anything() { 
    .... 
} 

正如你看到的,有沒有anything()定義當你使用它。但是,如果編譯單元包括a.htest.h之前),其本身包括test.h,它擴展爲這樣的事情:

/* INCLUDED FROM test.h */ 
inline void anything() { 
    .... 
} 

class Fooness{ 
public: 
Fooness(){ 
    anything(); 
    }; 
}; 

這樣的順序是正確的。

,使其在這兩種情況下工作,你可以在向前test.h,申報anything()你包括a.h前:

修正test.h版本

#ifndef TEST_H 
#define TEST_H 

void anything(); // forward-declaration 

#include "a.h" // <-- this is important to be *below* the forward-declaration 

inline void anything() { 
    .... 
} 

// more stuff 

#endif 

然後,當包括test.h(在a.h之前)時,它擴展到以下內容:

void anything(); 

/* INCLUDED FROM a.h */ 
class Fooness{ 
public: 
Fooness(){ 
    anything(); 
    }; 
}; 

inline void anything() { 
    .... 
} 
+2

那麼,它本身就是一個問題 - 它是一種循環依賴,可能永遠無法完全解決。 –

+0

@LightnessRacesinOrbit是的,我想強調你*可以交叉包含它(它不是被禁止的),但是*真正的問題是*符號依賴*,如果我們可以這樣稱呼它的話。 – leemes

1

確保「未聲明的標識符」即將anything()而不是ii我在operator<<看到...

相關問題