在編寫c++程式的時候,偶爾需要用到前置宣告(forward declaration)。下面的程式中,帶注釋的那行就是類b的前置說明。這是必須的,因為類a中用到了類b,而類b的宣告出現在類a的後面。如果沒有類b的前置說明,下面的程式將不同通過編譯,編譯器將會給出類似「缺少型別說明符」這樣的出錯提示。
**一:
// forwarddeclaration.h
#include
using
namespace
std;
class b; // 這是前置宣告(forward declaration)
class a
…};class b
;// main.cpp
#include "forwarddeclaration.h"
int main(int argc, char** argv)
上面程式可以順利編譯和執行(幾乎沒有做什麼,也沒有輸出)。
是不是有了前置說明就萬事大吉了呢?我們看看下面的**(帶陰影部分的**是新增加的):
**二:
// forwarddeclaration.h
#include
using
namespace
std;
class b; // 這是前置宣告(forward declaration)
class a
void somemethod()
};class b
};// main.cpp
#include "forwarddeclaration.h"
int main(int argc, char** argv)
一編譯,發現**(1)處出錯。出錯提示往往包括(不同的編譯器給出的提示會有所不同):
1. 使用了未定義的型別b;
2. 「->somemethod」的左邊必須指向類/結構/聯合/泛型型別
原因:
1. (1)處使用了型別b的定義,因為呼叫了類b中的乙個成員函式。前置宣告class b;僅僅宣告了有乙個b這樣的型別,而並沒有給出相關的定義,類b的相關定義,是在類a後面出現的,因此出現了編譯錯誤;
2. **一之所以能夠通過編譯,是因為其中僅僅用到b這個型別,並沒有用到類b的定義。
解決辦法是什麼?
將類的宣告和類的實現(即類的定義)分離。如下所示:
// forwarddeclaration.h 類的宣告
#include
using
namespace
std;
class b; // 這是前置宣告(forward declaration)
class a
;class b
;// forwarddeclaration.cpp 類的實現
#include "forwarddeclaration.h"
a::a(b* b):b(b)
void a::somemethod()
void b::somemethod()
// main.cpp
#include "forwarddeclaration.h"
int main(int argc, char** argv)
結論:
前置宣告只能作為指標或引用,不能定義類的物件,自然也就不能呼叫物件中的方法了。
而且需要注意,如果將類a的成員變數b* b;改寫成b& b;的話,必須要將b在a類的建構函式中,採用初始化列表的方式初始化,否則也會出錯。關於這點,詳見:特殊資料型別成員變數的初始化
**:
關於C 中的前置宣告
關於c 中的前置宣告 在編寫c 程式的時候,偶爾需要用到前置宣告 forward declaration 下面的程式中,帶注釋的那行就是類b的前置說明。這是必須的,因為類a中用到了類b,而類b的宣告出現在類a的後面。如果沒有類b的前置說明,下面的程式將不同通過編譯,編譯器將會給出類似 缺少型別說明符...
關於C 中的前置宣告
今天一朋友問及 c 中的前置宣告問題,下面是我給出的回答。在編寫c 程式的時候,偶爾需要用到前置宣告 forward declaration 下面的程式中,帶注釋的那行就是類 b的前置說明。這是必須的,因為類 a中用到了類 b,而類 b的宣告出現在類 a的後面。如果沒有類 b的前置說明,下面的程式將...
C 中前置宣告
有一定c 開發經驗的朋友可能會遇到這樣的場景 兩個類a與b是強耦合關係,類a要引用b的物件,類b也要引用類a的物件。好的,不難,我的第一直覺讓我寫出這樣的 a.h include b.h class a include a.h a a void a a void b.h include a.h cl...