C頭文件和源文件的連

http://blog.163.com/yui_program/blog/static/18415541520115177852896/函數

1、源文件如何根據#include來關聯頭文件ui

1,系統自帶的頭文件用尖括號括起來,這樣編譯器會在系統文件目錄下查找。spa

2,用戶自定義的文件用雙引號括起來,編譯器首先會在用戶目錄下查找,而後在到C++安裝目錄(好比VC中能夠指定和修改庫文件查找路徑,Unix和Linux中能夠經過環境變量來設定)中查找,最後在系統文件中查找。.net

#include 「"xxx.h」(我一直覺得」」和<>沒什麼區別,可是tinyxml.h是非系統下的都文件,因此要用」」)命令行

 

2、頭文件如何來關聯源文件設計

這個問題其實是說,已知頭文件「a.h」聲明瞭一系列函數,「b.cpp」中實現了這些函數,那麼若是我想在「c.cpp」中使用「a.h」中聲明的這些在「b.cpp」中實現的函數,一般都是在「c.cpp」中使用#include 「a.h」,那麼c.cpp是怎樣找到b.cpp中的實現呢?xml

其實.cpp和.h文件名稱沒有任何直接關係,不少編譯器均可以接受其餘擴展名。好比偶如今看到偶們公司的源代碼,.cpp文件由.cc文件替代了。blog

在Turbo C中,採用命令行方式進行編譯,命令行參數爲文件的名稱,默認的是.cpp和.h,可是也能夠自定義爲.xxx等等。get

譚浩強老師的《C程序設計》一書中提到,編譯器預處理時,要對#include命令進行「文件包含處理」:將file2.c的所有內容複製到#include 「file2.c」處。這也正說明了,爲何不少編譯器並不care到底這個文件的後綴名是什麼----由於#include預處理就是完成了一個「複製並插入代碼」的工做。編譯器

編譯的時候,並不會去找b.cpp文件中的函數實現,只有在link的時候才進行這個工做。咱們在b.cpp或c.cpp中用#include 「a.h」其實是引入相關聲明,使得編譯能夠經過,程序並不關心實現是在哪裏,是怎麼實現的。源文件編譯後成生了目標文件(.o或.obj文件),目標文件中,這些函數和變量就視做一個個符號。在link的時候,須要在makefile裏面說明須要鏈接哪一個.o或.obj文件(在這裏是b.cpp生成的.o或.obj文件),此時,鏈接器會去這個.o或.obj文件中找在b.cpp中實現的函數,再把他們build到makefile中指定的那個能夠執行文件中。

    在Unix下,甚至能夠不在源文件中包括頭文件,只須要在makefile中指名便可(不過這樣大大下降了程序可讀性,是個很差的習慣哦^_^)。在VC中,一幫狀況下不須要本身寫makefile,只須要將須要的文件都包括在project中,VC會自動幫你把makefile寫好。

一般,編譯器會在每一個.o或.obj文件中都去找一下所須要的符號,而不是隻在某個文件中找或者說找到一個就不找了。所以,若是在幾個不一樣文件中實現了同一個函數,或者定義了同一個全局變量,連接的時候就會提示「redefined」。

 

內部鏈接和外部鏈接:

編譯時每一個文件會被編譯成一個含有必要信息的源文件(又叫編譯單元),而後編譯單元會聯結成一個和主文件同名的.o文件,.o文件把不一樣的編譯單元中產生的符號聯繫起來,構成一個可執行文件。有兩種大相徑庭的連接:內部的和外部的,將這些編譯單元聯繫起來。

內部鏈接:對這個定義的訪問被侷限在當前編譯單元,其餘編譯單元沒法訪問。

外部鏈接:可被其餘單元訪問,所以名稱在整個執行文件中必須惟一。

類的定義(同時也是聲明),enum,struct,都是內部鏈接,內聯函數,靜態的非類成員數據也是

typedef聲明的類型也是內聯結。

非內聯成員函數(包括靜態成員)有外部鏈接,非內聯函數,非靜態自由函數(非類的成員函數)也是外鏈接。

聲明只對當前編譯單元有用,他們不會影響到.o文件

.h文件,因爲該文件會被其餘.cpp文件包含,但因爲聲明只是對當前編譯單元有效,是不會將符號引入.o文件,因此該文件不能含有任何外部鏈接的符號(數據成員和函數)的定義。通常狀況下也不要包含內鏈接符號的定義。

綜上所訴:

.h文件中能包含:

1。類成員數據的聲明,但不能賦值

2.類靜態數據成員的定義和賦值,但不建議,只是個聲明就好。

3。類的成員函數的聲明

4。非類成員函數的聲明

5.常數的定義:如:const int a=5;

6.靜態函數的定義

7.類的內聯函數的定義

不能包含:

1. 全部非靜態變量(不是類的數據成員)的聲明

2。 默認命名空間聲明不要放在頭文件,using namespace std;等應放在.cpp中,在.h文件中使用std::string

http://blog.csdn.net/pjw100/archive/2010/01/18/5208879.aspx

 

----------------------------------------------------------------------------------------------------------------------

編譯器無論頭文件的,頭文件只是用來被cpp文件包含的,被包含以後,它就成了那個cpp文件的一部分了,而編譯器只編譯.cpp文件,不會去單獨編譯一個頭文件的。編譯器這樣作以後,針對每一個編譯過的cpp文件生成一個obj文件。而後鏈接器把全部這些obj文件鏈接成一個程序,或能是exe或dll(或作成靜態的lib)。若是在鏈接的過程當中,有些實體(好比變量或函數)找不到定義,則會報link錯誤。

 

咱們一般把類的定義都放在頭文件,而其成員函數以及靜態成員變量的定義都放在一個主名相同,擴展名不一樣的cpp文件——這只是一種風格和傳統,而不是C++語言規定的。

若是你不嫌亂,你固然能夠把全部的代碼都放到一個cpp文件中,整個工程就一個源文件。

你也能夠把一個類的10個函數分別在10個不一樣的cpp文件中實現,甚至有4個實如今cpp文件中,另外3個是打包在之前作好的靜態庫(lib)中,還有3個內聯定義在頭文件中——都沒問題。只要每一個cpp文件都能順利經過編譯,並且鏈接器在鏈接時都能找到這些定義就OK了。

相關文章
相關標籤/搜索