2012-02-09 36 views
10

我有聲明方法但未實現它的Class。該方法不是一個虛擬功能。在相應的cpp文件中,我沒有找到相同方法的定義。定義了該類中聲明的所有其他方法。在Class中聲明但未定義的方法

我編譯的代碼,它很好。我的印象是,cpp必須強制聲明方法的定義。

欣賞是否有人能詳細說明。我使用VS2010的編譯器。

回答

10

你的代碼會被編譯,但會給出鏈接錯誤。

建設項目的可執行包括兩個階段:

  • 編譯
  • 鏈接

編譯編譯器通過驗證語言語義只是將源代碼轉換成目標代碼。
鏈接鏈接器實際上查找符號的定義並從多個對象文件(在編譯期間創建)創建一個可執行文件。

編譯器分別編譯每個翻譯單元(.cpp +頭文件)中的源代碼,因此它假定該定義應該存在於某個其他源文件中。鏈接器試圖找到對函數定義的引用,因此缺失的定義將由鏈接器報告。

注意鏈接器需要鏈接只有那些你的程序中使用符號,
對於例如:如果你的程序中聲明瞭一個功能,沒有提供定義&然後再也用途/隨時隨地調用功能,鏈接器不需要嵌入用於跳轉到函數的目標代碼駐留在任何函數調用位置的地址的代碼。
鑑於這種情況,鏈接器根本就不需要查找函數定義。因此,代碼將編譯和鏈接。

+5

恕我直言,鏈接錯誤只會發生在具有缺失定義的函數被明確/隱式地使用/調用的地方。 – fizzbuzz 2012-02-09 12:02:05

+0

@fizzbuzz:是的,當然。這是基本標準。 – 2012-02-09 14:19:34

+0

我既沒有收到任何編譯或鏈接錯誤。只是爲了補充我沒有在任何地方使用funtion。代碼編譯並鏈接到.lib文件中。 – akrohit 2012-02-09 15:23:22

3

沒有要求在特定文件中實現該方法。事實上,它被認爲是一種很好的編程習慣,每種方法都有一個文件可以在與庫鏈接時減少膨脹。

這意味着給定一個定義類的頭文件(並且可能沒有實現),編譯器只能假定所有函數都在某處實現。它只是在系統試圖將所有東西放在一起(鏈接階段)的地步,這就表明你指的是那些不存在的東西。

+0

每**方法一個文件**?似乎過度... – 2012-02-09 11:38:44

+0

不是真的。它使得更少的膨脹和令人驚訝的鏈接問題。一些現代編譯器通過使每個函數處於單獨的對象部分來實現這種必要性,但大多數編譯器不這樣做。 – 2012-02-09 12:51:07

+0

我再次檢查,並找不到我在上面在任何其他文件中也談論的方法的定義。 – akrohit 2012-02-09 15:24:15

3

這是防止分配或複製的常用技術。如果你聲明但沒有定義它,如果你嘗試使用它,就會發生鏈接錯誤,即防止人們無意中使用它。

0

編譯器沒有抱怨,因爲沒有語法/編譯器錯誤。 鏈接器不會投訴,因爲您沒有調用程序中的函數,因此無需鏈接。

相關問題