清除 Visual Studio 中的 C/C++ 包含
從 Visual Studio 17.8 Preview 1 開始,Visual Studio 提供 #include
清除功能,以下列方式改善程式碼的品質:
- 僅因為需要標頭檔會由另一個標頭檔間接包含,因此提供新增程式碼的標頭檔。
- 移除未使用的標頭檔 -- 改善建置時間和程式碼清潔的供應專案。
Include Cleanup 預設為開啟。 若要瞭解如何進行設定,請參閱 在 Visual Studio 中設定 C/C++ Include Cleanup。
直接與間接標頭
首先,一些術語:
- 直接標頭是您明確
#include
在程式碼中的標頭。 - 間接標頭是您未明確
#include
表示的標頭。 相反地,您直接包含的標頭檔會包含它。 我們也表示包含transitively
間接標頭。
包含清除會分析您的程式碼,並判斷未使用哪些標頭,以及哪些標頭會間接包含。 請考慮下列標頭檔:
// myHeader.h
#include <string>
#include <iostream>
void myFunc()
{
std::string s = "myFunc()\n";
std::cout << s;
}
以及使用它的程式:
// myProgram.cpp
#include "myHeader.h"
int main()
{
std::string s = "main()"; // string is indirectly included by myHeader.h
std::cout << s; // cout is indirectly included by myHeader.h
myFunc();
}
myHeader.h
是直接標頭,因為 myProgram.cpp
明確包含它。 myHeader.h
包含 <string>
和 <iostream>
,因此這些是間接標頭。
問題是 myProgram.cpp
使用 std::string
和 std::cout
,但不直接包含定義它們的標頭。 此程式碼會發生編譯,因為 myHeader.h
包含這些標頭。 此程式碼很脆弱,因為如果 myHeader.h
曾經停止包含其中一個程式碼, myProgram.cpp
就不會再編譯。
根據 C++ 指導方針,最好明確包含所有相依性的標頭,讓您的程式碼不受標頭檔變更所造成的脆弱。 如需詳細資訊,請參閱 C++ 核心指導方針 SF.10 。
包含清除會分析您的程式碼,以識別未使用和間接包含的標頭。 它會根據 Visual Studio 中設定 C++ #include 工具中所述 的設定提供意見反應。 意見反應可以是錯誤清單警告、建議等形式。如需 Include Cleanup 所提供意見反應的詳細資訊,請參閱 包含清除訊息 。
未使用的標頭
隨著程式碼的發展,您可能不再需要一些標頭檔。 這很難在複雜的專案中追蹤。 一段時間後,您的組建可能需要更長的時間,因為編譯器正在處理不必要的標頭檔。 包含清除可協助您尋找和移除未使用的標頭。 例如,如果在 myFunc()
中 myProgram.cpp
加上批註,該怎麼辦:
// myProgram.cpp
#include "myHeader.h"
int main()
{
std::string s = "main()"; // string is indirectly included from myHeader.h
std::cout << s; // cout is indirectly included from myHeader.h
// myFunc(); // directly included from myHeader.h
}
在下列螢幕擷取畫面中, #include "myHeader.h"
會呈現暗灰色(Visual Studio 中設定 C++ #include 工具中所述 的設定),因為它不會因為已批註而使用 myFunc()
。
將游標暫留在暗灰色 #include
上方,以顯示快速動作功能表。 按一下燈泡(或選擇 [ 顯示潛在修正連結 ] 以查看與未使用檔案相關的動作:
新增可轉移使用的標頭
我們可以選擇移除未使用的標頭檔,但這會中斷程式碼,因為 <string>
和 <iostream>
是透過 myheader.h
間接包含。
相反地,我們可以選擇 [ 新增所有可轉移使用的] 並移除所有未使用 #includes 。 這會移除未使用的標頭 myHeader.h
,但也會新增透過 間接包含 myHeader.h
的任何標頭。 在此情況下,結果會將 和 #include <iostream>
新增 #include <string>
至 myProgram.cpp
,並移除 #include "myHeader.h"
:
// myProgram.cpp
#include <iostream>
#include <string>
int main()
{
std::string s = "main()"; // string is directly included from <string>
std::cout << s; // cout is directly included from <string>
// MyFunc();
}
此工具不會更新批註,但您可以看到程式碼現在使用 且直接使用 std::string
。 std::cout
此程式碼不再脆弱,因為它不相依 myHeader.h
于包含其他必要標頭。
最佳做法
請勿移除看似未使用標頭檔的內容,而不先新增間接包含的標頭檔。 這是因為您的程式碼可能依賴間接包含在未使用的標頭檔中。 先新增可轉移使用的標頭。 然後,當您移除未使用的標頭時,由於已移除標頭檔間接包含的標頭檔遺失,所以不會收到編譯錯誤。
若要這樣做,其中一種方法是設定 [新增遺漏的包含 建議層級] 的建議層級 ( 工具 > 選項 > 文字編輯器 > C/C++程式 > 代碼清除)。 此外,將 [移除未使用的包含建議] 的建議層級 設定為 [建議 ]。 接下來:
- 在錯誤清單中,確定篩選準則設定為 [建置 + IntelliSense ]。
- 尋找「來自 #include x 的內容用於此檔案中並暫時包含」的實例。
- 將游標暫留在具有建議的行上。 從燈泡下拉式清單中,選取 [ 新增所有可轉移使用的包含 ]。
- 重複專案中的這些步驟,直到解決所有有關可轉移包含的建議為止。
- 移除未使用的 include:在錯誤清單中,尋找 「#include x 未用於此檔案」的實例。
- 將游標暫留在未使用的標頭上。 從燈泡下拉式清單中,選取 [ 移除所有未使用的專案]。
- 重複專案中的這些步驟,直到解決所有 Include Cleanup 建議為止。
在此簡短概觀中,您已瞭解 Include Cleanup 如何協助您移除未使用的標頭,以及新增間接包含的標頭。 這可協助您保持程式碼乾淨、可能更快速地建置,並減少程式碼的脆性。