在.cpp文件中轉發類定義有什麼意義?在cpp文件中聲明一個轉發的類定義,用於什麼?
想象一下,我在另一個公共類中有一個私人類。我轉發私有類的定義,比如Private類。
將我的私有類的聲明放在.cpp文件中還是有優勢的,或者我應該在我的public class.h中堅持使用我的forward聲明並將我的privateClass.h包含在cpp文件中?
在.cpp文件中轉發類定義有什麼意義?在cpp文件中聲明一個轉發的類定義,用於什麼?
想象一下,我在另一個公共類中有一個私人類。我轉發私有類的定義,比如Private類。
將我的私有類的聲明放在.cpp文件中還是有優勢的,或者我應該在我的public class.h中堅持使用我的forward聲明並將我的privateClass.h包含在cpp文件中?
內部類和結構通常最好不要使用公共標題以避免依賴和耦合。
如果東西在公共頭中,這意味着如果實現細節(在私有類/結構中)發生更改,公共頭將不得不更改。這很糟糕,因爲客戶端程序實際上需要重新編譯(在ODR下 - 一個定義規則)以及各種實現定義的關於類/ vtable佈局和名稱修改的後果。
一旦你能避免依賴於你的完整私有類型的定義,你會避免一切不必要的依賴關係,導致
一個前向聲明的類被稱爲'不完整類型',直到它被定義(通常在一個私人頭文件或簡單地在cpp文件本身)。直到那一刻,只有地址引用,引用傳遞或指針傳遞才被允許。 有時不完整的類可能會導致棘手的語義情況;不完整類型的對象銷燬將假定爲非虛擬析構函數(某些編譯器可以檢測到這一點,並警告實際定義是否引入了虛擬析構函數)。在定義不完整類型的智能指針時,這起着重要作用,例如,在流行的pImpl習語中。如有疑問,請使用智能指針庫的文檔(例如Boost SmartPtr)。
更新添加背景資料的鏈接,因爲這是一個越來越普遍的回答:
原因是您的.h
文件應該只包含描述由公共類表示的模塊接口的代碼。在這種情況下,Private
類的聲明和定義是關於模塊接口的一個實現,並且不提供如何使用接口的信息。
正向聲明的要點是在沒有定義的情況下使用該類的能力。你可以只轉發聲明類Private,並且使用指針或對該類的對象的引用,而不包括任何頭文件或在該文件或包含的文件中定義類本身。
如果您將私有類聲明放入一個頭文件中,那麼基本上它不再是私有的,因爲任何人都可以包含該文件。因此,要麼將其隱藏在另一個類的聲明中,要麼儘可能在cpp文件中聲明它。
類轉發通常用在頭文件中。例如:
// Class2.h
class Class1;
class Class2
{
Class1* m_class1; // Using Class1 type
};
這允許Class2.h使用Class1而無需在其頭文件中包含Class1.h。當然任何包含Class2.h的.cpp文件也必須包含Class1.h。
請記住,您可以在多個模塊中聲明類型,但只能在其中一個模塊中定義類型。
此代碼不會編譯,因爲您不能使用不完整的類型Class1 – sehe 2011-05-23 13:17:06
@sehe:糟糕,您是對的,它只適用於指針。編輯。 – Tergiver 2011-05-23 13:24:04
或參考。一般來說,大多數不依賴於類佈局等細節的東西都可以工作。 – sehe 2011-05-23 13:27:19