簡體   English   中英

我是否在頭文件中使用標准庫預處理器包含相應的實現文件是否重要?

[英]Does it matter whether I use standard library preprocessor includes in my header file vs. the corresponding implementation file?

如果我有一個項目

main .cpp 
Knife .h and .cpp
Cucumber .h and .cpp 

我想在Cucumber中使用Knife的成員,我是否使用以下內容是否重要:

#include "Knife.h"
#include <iostream>
using namespace std;

在Cucumber.h或Cucumber.cpp中(假設Cucumber.cpp已經包含了Cucumber.h)?

我的建議是盡量減少頭文件中包含的文件數量。 所以,如果我有選擇,我更願意包含在源文件中。

修改頭文件時,必須重新編譯包含此頭文件的所有文件。

因此,如果cucumber.h包含knife.hmain.cpp包含cucumber.h ,並且您修改了knife.h ,則將重新編譯所有文件( cucumber.cppknife.cppmain.cpp )。

如果cucumber.cpp包含knife.hmain.cpp包含cucumber.h ,並且修改了knife.h ,則只會重新編譯cucumber.cppknife.cpp ,因此編譯時間會縮短。

如果你需要在黃瓜中使用刀,你可以這樣做:

// Cucumber.hpp
#ifndef CUCUMBER_HPP
#define CUCUMBER_HPP

class Knife;

class Cucumber
{
public :
///...
    private :
    Knife* myKnife
}
#endif

//Cucumber.cpp
#include "Cucumber.hpp"
#include "Knife.hpp

// .. your code here

這個“技巧”被稱為“前瞻性宣言”。 這是C ++開發人員眾所周知的技巧,他們希望最大限度地縮短編譯時間。

是的,你應該把它放在.cpp文件中。

你將擁有更快的構建,更少的依賴,更少的工件和噪音 - 在iostream的情況下,GCC聲明:

// For construction of filebuffers for cout, cin, cerr, clog et. al.
static ios_base::Init __ioinit;

在命名空間std 如果Knife.h包含在許多文件中,那么聲明將產生大量(冗余)靜態數據,這些數據必須在啟動時構建。 所以有很多勝利,唯一的損失是你必須明確包含你真正需要的文件 - 你需要的每個地方(在某些方面這也是一件非常好的事)。

我所看到的建議是僅包含給定源文件所需的最小值,並盡可能多地保留標題。 在編譯時,它可能會減少依賴性。

另一件需要注意的是命名空間的使用。 你肯定要小心在標題中有這樣的東西。 它可以更改您未計划的文件中的命名空間使用情況。

作為一般規則,嘗試將您的包添加到實現文件而不是標頭中,原因如下:

  • 減少潛在的不必要的包含,並將其保留在需要的地方。
  • 減少編譯時間(在我見過的某些情況下非常顯着。)避免暴露實現細節。
  • 降低出現循環依賴的風險。
  • 避免將標頭的用戶鎖定為必須間接包含他們可能不需要/不需要的文件。

如果您只通過標題引用一個類或引用,那么就沒有必要包含適當的標題; 一個類聲明就足夠了。

可能還有其他一些原因 - 上述可能是最重要/最明顯的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM