2015-07-13 37 views
2

考慮下面的代碼:

//header.h 
#pragma once 

class A 
{ 
public: 
    A(); 
    void f(); 
}; 

//header.cpp 
#include "header.h" 

A::A(){} 
void A::f(){} 

//main.cpp 
#include "header.h" 

int main() 
{ 
    A a; 
    a.f(); 
} 

編譯器,如何知道哪兒是constructorf函數的聲明,因爲只有在header.h列入main.cpp?以及爲什麼不能找到相同的功能,當class A是模板?

+0

函數(包括構造函數)可以用符號表示。鏈接器查找所有符號,並用實際的代碼地址替換它們。 –

+0

[編譯/鏈接過程如何工作?]可能的重複(http://stackoverflow.com/questions/6264249/how-does-the-compilation-linking-process-work) –

+0

對於你最後一個問題,請參見[爲什麼只能在頭文件中實現模板](http://stackoverflow.com/q/495021/597607) –

回答

4

編譯單元不需要定義,只是聲明

鏈接器將確保所有函數定義可以從所有組成的編譯單元中找到。

模板類僅在使用點實例化,並且在逐個函數的基礎上。正因爲如此,模板類傾向於在標題中完全定義。

6

讓我給你看看這個圖片: c++ flow http://faculty.cs.niu.edu/~mcmahon/CS241/Images/compile.png

編譯過程是這樣的:

  1. C++預處理器複製包含的頭文件到源代碼文件的內容,產生宏代碼,並用#define定義的符號常量替換它們的值。

  2. 將由C++預處理器生成的擴展源代碼文件編譯爲該平臺的彙編語言。

  3. 編譯器生成的彙編代碼被彙編到平臺的目標代碼中。

  4. 由彙編程序生成的目標代碼文件與任何用於生成可執行文件的庫函數的目標代碼文件鏈接在一起。

+0

這似乎沒有真正回答OP的問題? –

+0

我認爲這並不取決於你是否使用OP。由於C++編譯器用於使事情工作的基本規則是相同的。類定義就是「模板」,當你在你的代碼中使用某些部分時,編譯器會展開。 – Ashot

+0

OP ==原始海報 –