2013-04-05 81 views
16

我有一個B類,我想打電話給成員形成類A.所以:包含在頭文件與前瞻性聲明,包括在的.cpp

1.

//A.h  
class B; 
class A 
{ 
private: 
    B* m_p; 
}; 

//a.cpp 
#include "B.h" 

2。

// A.h 
#include "B.h" 

class A 
{ 
private: 
    B * impl_; 
}; 

哪種方式比較好,這兩種類似,當一個小項目不依賴太多的涉及?

+0

確實喜歡:'#include「B.h」' – 2013-04-05 07:13:17

+0

啊,我會小心的...... – colddie 2013-04-06 06:49:33

回答

23

做的你的第一個方式是指在a.h,該存在class B是已知的,但不是它的定義。這限制了Ba.h內可以做什麼。例如,可以使用B *類型的變量,但不能使用B類型的變量(因爲要聲明B類型的變量,編譯器必須能夠看到B的完整定義)。另外,如果您有B *類型的變量,則不能取消引用指針(因爲也必須知道B的定義)。

因此,您的第二個選擇–哪些沒有這些問題–是首選,這是大多數人使用大多數時間。

這只是第一種方法可能有用的特殊情況。例如:

  • 如果.h文件包括彼此(但你可能會得到一些更多的問題,也包括有關的得分後衛,這是很難的,並且要避免的);
  • 如果b.h非常大且複雜,所以您希望儘可能避免包含它,因爲它會減慢編譯過程。
0

只是聲明類中的A類的標題。

class B; 
0

第二個比較好。它使B類成爲您使用.h文件包含的模塊。考慮將來子集B的情況,並且您將A更新爲使用C。在第二種情況下,您只能替換標頭#includeA的化妝品。在第一種情況下,您必須更改前向聲明。另外,在第二種情況下,您定義的不僅僅是符號B

而且作爲註釋,你應該使用#include "B.h"如果頭文件在同一目錄作爲代碼的其餘部分。

0

那麼你正在做的是叫做向前decleration什麼,你想,其原因是,如果你有這樣的事情類A使用類B以及B類使用A級

在的情況下只有一種關係,你當然可以使用你的第二選擇。 如果您需要雙重用法,那麼至少有一個類的刪除將不得不使用正向刪除

7

答案:。
看看http://www.umich.edu/~eecs381/handouts/handouts.html

C Header File Guidelines

C++ Header File Guidelines(由大衛Kieras,EECS系,美國密歇根大學)說:

指引#10。 如果X類型的不完整聲明將執行,則使用 而不是#包含其頭X.h。如果另一個結構或類 X型只出現在中 內容的標題連接文件,那麼你不應該#包括XH,只是把X的 不完整的申報指針或引用類型(也稱爲「正向」的聲明)附近 頭連接文件的開頭,如:class X;見講義 Incomplete Declarations這個強大而 有價值的技術的更多討論。請注意,標準庫包含不完整的聲明,往往蘇夫網絡CES的<iostream> 圖書館,名爲<iosfwd>的頭 。 #include <iosfwd>只要有可能,因爲 頭文件的文件非常大(巨模板!)。

12

你的第一種方法是向前聲明。你的第二個實際上包括類B.

什麼時候使用一個?

使用第一個時:

  • 定義A的,你只有一個指針到B,即不B.成員
  • 你永遠不會從調用B的任何功能A的定義(即所有對B的成員函數的調用發生在實際實現A的成員函數的.cpp文件中。)
  • 您期望B類的接口或大小經常更改,但不是A的接口。這樣,如果B改變了,只有a.cpp的內容得到重新編譯,但是a.h(和其他包含a.h的文件)不需要改變。

使用第二個時:

  • 你需要知道大小 B的編譯器使用其類的定義和其所有成員的大小計算類的大小。例如,如果類A有一個類型爲B的成員,那麼爲了計算A的大小,編譯器需要知道B的大小;要知道B的大小,你需要包含b.h.
    • 您需要調用類B的函數。爲了知道您是否調用實際存在的函數,編譯器需要知道類B的接口,即您需要包含b.h.