簡體   English   中英

有沒有辦法在VC ++中使用預編譯的頭文件而不需要stdafx.h?

[英]Is there a way to use pre-compiled headers in VC++ without requiring stdafx.h?

我有一堆遺留代碼,我需要編寫單元測試。 它在任何地方使用預編譯的頭文件,因此幾乎所有.cpp文件都依賴於stdafx.h,這使得為了編寫測試而難以破壞依賴性。

我的第一直覺是刪除所有這些stdafx.h文件,這些文件大部分都包含#include指令,並根據需要將#includes直接放在源文件中。

這將使得必須關閉預編譯的頭文件,因為它們依賴於像stdafx.h這樣的文件來確定預編譯頭文件的停止位置。

有沒有辦法保留沒有stdafx.h依賴項的預編譯頭文件? 有沒有更好的方法來解決這個問題?

是的,還有更好的方法。

問題,恕我直言,預編譯標題的'向導樣式'是他們鼓勵不需要的耦合,並使重用代碼比它應該更難。 此外,使用“只是堅持stdafx.h中的所有內容”樣式編寫的代碼很容易維護,因為更改任何頭文件中的任何內容都可能導致整個代碼庫每次都重新編譯。 這可以使簡單的重構永遠,因為每個更改和重新編譯周期都需要更長的時間。

恕我直言,更好的方法是使用#pragma hdrstop和/ Yc和/ Yu。 這使您可以輕松設置使用預編譯頭的構建配置,還可以構建不使用預編譯頭的配置。 使用預編譯頭文件的文件與源文件中預編譯頭文件本身沒有直接依賴關系,這使得它們可以使用或不使用預編譯頭進行構建。 項目文件確定哪個源文件構建預編譯頭文件,並且每個源文件中的#pragma hdrstop行確定哪些包含從預編譯頭文件(如果使用)中獲取,哪些包含直接從源文件中獲取...這意味着當進行維護時,您將使用不使用預編譯頭的配置,並且只有在頭文件更改后重建所需的代碼才會重建。 完成構建時,您可以使用預編譯的頭配置來加速編譯過程。 使用非預編譯的頭部構建選項的另一個好處是,它確保您的cpp文件僅包含他們需要的內容並包含他們需要的所有內容(如果您使用預編譯頭的'向導樣式',則很難。

我在這里寫了一些關於它如何工作的文章: http//www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html (忽略關於/ FI的東西)我有一些使用#pragma hdrstop和/ Yc / Yu方法構建的示例項目: http//www.lenholgate.com/blog/2008/04/practical-testing-16- --fixing-a-timeout-bug.html

當然,從“向導式”預編譯頭文件使用到更加受控的樣式通常是非常重要的......

當您通常使用預編譯頭時,“stdafx.h”有兩個目的。 它定義了一組穩定的,通用的包含文件。 同樣在每個.cpp文件中,它用作預編譯頭文件結束位置的標記。

聽起來你想要做的是:

  • 保持預編譯標頭已打開。
  • 將“stdafx.h”包含在每個.cpp文件中。
  • 清空“stdafx.h”中的包含。
  • 對於每個.cpp文件,找出舊的“stdafx.h”中需要哪些包含。 在每個.cpp文件中的#include“stdafx.h”之前添加這些。

因此,現在您擁有最小的依賴項集,並且您仍在使用預編譯的標頭。 遺失的是,您不是只預編譯一組常用標題。 這對於完全重建來說將是一個巨大的打擊。 對於開發模式,您只需要一次重新編譯一些文件,它就不那么受歡迎了。

不,可能沒有更好的方法。

但是,對於給定的單個.cpp文件,您可能認為不需要預編譯頭。 您可以修改該.cpp文件的設置並刪除stdafx.h行。

(實際上,我不知道預編譯的頭部方案如何干擾您的單元測試的編寫)。

編號預先編譯的頭文件依賴於以這種方式編譯的所有源包含的單個頭。 您可以指定單個源(或全部)根本不使用預編譯的頭,但這不是您想要的。

過去,Borland C ++編譯器在沒有特定標頭的情況下進行了預編譯。 但是,如果兩個源文件包含相同的頭但順序不同,則它們是單獨編譯的,因為實際上,C ++中頭文件的順序可能很重要......

因此,這意味着borland預編譯的標題確實可以節省時間,只有當您非常嚴格地包含相同順序的源,或者包含(首先)所有其他文件的單個包含文件時... - 聽起來很熟悉?!?!

是。 “stdafx.h / stdafx.pch”名稱只是慣例。 您可以為每個.cpp提供自己的預編譯頭。 通過一個小腳本來編輯.vcproj中的XML可能最容易實現。 缺點:你最終會得到一大堆預編譯的標題,並且它們不會在TU之間共享。

可能,但聰明? 我不能肯定地說。

我的建議是 - 除非你想讓你的構建變得非常緩慢,否則不要刪除預編譯的頭文件。 你基本上有三個選擇:

  1. 擺脫預編譯的頭文件(不推薦)
  2. 為遺留代碼創建單獨的庫; 這樣你就可以單獨構建它。
  3. 在單個項目中使用多個預編譯頭。 您可以在解決方案資源管理器中選擇單個C ++文件,並告訴它們使用哪個預先推薦的標頭。 您還需要設置OtherStdAfx.h / cpp以生成預編譯頭。

預編譯的頭文件的前提是所有內容都包含相同的內容。 如果您想使用預編譯的頭文件,那么您必須使用這意味着的依賴項。 它歸結為依賴關系與構建速度的權衡。 如果你可以在一個合理的時間內建立關閉預編譯的標題,那么一定要做。

另一件需要考慮的事情是每個庫可以有一個pch。 因此,您可以將代碼拆分為較小的庫,並使每個庫都具有更嚴格的依賴關系。

我只對需要包含afx___內容的代碼使用預編譯頭文件 - 通常只是UI,我不進行單元測試。 UI代碼處理UI並調用具有單元測試的函數(盡管大多數當前不是由於應用程序是遺留的)。

對於大部分代碼,我不使用預編譯的頭文件。

G。

預編譯頭可以在重建項目時節省大量時間,但如果預編譯頭更改,則將重新編譯取決於頭的每個源文件,無論更改是否影響它。 幸運的是,預編譯的頭文件用於編譯 ,而不是鏈接 ; 每個源文件都不必使用相同的預編譯頭。

pch1.h:

#include <bigHeader1.h>
#include ...


pch1.cpp:

#include "pch1.h"


source1.cpp:

#include "pch1.h"
[code]


pch2.h:

#include <bigHeader2.h>
#include ...


pch2.cpp:

#include "pch2.h"


source2.cpp

#include "pch2.h"
[code]

選擇pch1.cpp ,右鍵單擊, 屬性,配置屬性,C / C ++,預編譯頭
預編譯標題:創建(/ Yc)
預編譯的頭文件: pch1.h
預編譯的頭文件輸出文件 :$(intDir)pch1.pch

選擇source1.cpp
預編譯標題:使用(/ Yu)
預編譯的頭文件: pch1.h
預編譯的頭文件輸出文件 :$(intDir)pch1.pch(我覺得這不重要/ Yu)

pch2.cppsource2.cpp執行相同的操作 ,除了將頭文件頭文件輸出文件設置pch2.hpch2.pch 這對我行得通。

暫無
暫無

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

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