關於C 中的前置宣告

2021-08-13 04:05:53 字數 1900 閱讀 3521

在編寫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...