[英]Separate header files for concrete classes - C++
背景
我有一個抽象類,類似於
class IConverter{
public:
virtual void DoConvertion() = 0;
};
將有許多具體的類只是實現DoConvertion方法。
class TextConverter : public IConverter{
public:
virtual void DoConvertion(){
// my code goes here
}
};
class ImageConverter : public IConverter{
public:
virtual void DoConvertion(){
// my code goes here
}
};
這樣會有很多具體的實現。 我創建了一個頭文件,比如說CharacterConverter.h ,它有一個抽象類IConverter 。
題
由於我的具體類只實現了DoConvertion方法,是否需要為每個具體類創建單獨的頭文件? 我的意思是它需要為所有具體類創建ImageConverter.h , TextConverter.h等等嗎? 所有這些頭文件都將包含與IConverter抽象類相同的代碼。
有什么想法嗎?
這不是必需的。 這基本上是一個判斷電話。
如果每個類的實現都很簡單,你可以將它們全部放在一個.h和一個.cpp中
如果實現有點長,那么為每個實現使用單獨的.h和.cpp文件可能更簡潔。
為每個類使用不同的.h / .cpp的一些優點:
你可能會得到兩種方式的答案。
我會說,對於任何簡單的轉換器,將它們全部放在一個.h / .cpp對中就足夠了,將每一個分成一對就太過分了。 我認為在這種情況下,維護大量文件與在一個文件中維護一堆方法的權衡是值得的。
復雜的轉換可能值得擁有自己的文件對。
您將需要具體類的定義來創建對象,因此您需要將這些定義放在某個.h文件中。 你把它們放在哪個文件取決於你。
對此最好的答案是更容易閱讀。 一個很長的源文件對你和其他程序員來說很難跟上。 另一方面,許多微小的(半屏幕完整)源文件同樣糟糕。
你可以考慮的東西,取決於你的設計的其余部分,是一個工廠,你的抽象類有一個靜態方法(或多個靜態方法,取決於你如何實現它)構建適當的子類並將其作為IConverter返回* 。 這樣,您可以只在頭文件中公開抽象定義,並在單個.cpp文件中包含所有具體的類定義和實現以及超類實現。 如果您的子類很大,這會變得有點笨拙,但是如果類較小,則會減少您必須管理的文件數量。
但是,正如其他人所指出的那樣,這最終是一種判斷。 唯一的性能問題與編譯有關; 更多的cpp文件可能需要(稍微)更長的時間來編譯,更多的頭文件可能會增加依賴性分析。 但是並不要求每個頭文件都有匹配的cpp和反之亦然。
根據評論,我建議這樣的結構:
IConverter.h ==> IConverter的定義
Converters.h ==>所有子類的定義
IConverter.cpp ==>包括IConverter.h和Converters.h,包含IConverter抽象功能的實現(靜態工廠方法和任何可繼承的功能)
TextConvter.cpp,ImagerConverter.cpp等等==>每個子類的單獨cpp文件,每個子類包含IConverter.h和Converters.h
這允許您僅在使用工廠和通用功能的任何客戶端中包含IConverter.h。 將所有其他定義放在單個標題中,如果它們基本相同,則可以合並。 單獨的cpp文件允許您利用Brian提到的編譯器優勢。 您可以如上所述內聯頭文件中的子類定義,但這並不能真正為您帶來任何好處。 在內聯等優化方面,您的編譯器通常比您更聰明。
創建接口類的一個要點是,客戶端可以依賴於抽象接口而不是具體實現,然后您可以自由地更改實現而不會影響客戶端。
將具體聲明放在與接口聲明相同的頭文件中會使其失敗,所以現在如果更改具體類的實現細節,則客戶端需要重新編譯。
使用工廠或函數指針可能會更好。
然而,一種特別令人討厭的方式是使用宏來聲明你的具體類。 例如:
在IConverter.h的底部包含以下宏
#define DECLARE_CONVERTER_CLASS(CLASS_NAME) \
class CLASS_NAME : public IConverter\
{ \
public: \
CLASS_NAME() {} \
virtual void DoConversion(); \
}; \
然后在MyConverter1.cpp中
DECLARE_CONVERTER_CLASS(MyConverter1)
virtual void MyConverter1::DoConversion()
{
...
}
哎呀:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.