是這樣的,在學習鄭莉老師的多文件結構和編譯預處理命令章節時候,看到書裏有這麼一張圖描述以下:#include指令做用是將指定的文件嵌入到當前源文件中#include指令所在的位置。
c++
而後我就想5_10.cpp主程序直接include了point.cpp也能夠吧(由於point.cpp裏include了point.h,這樣既有聲明又有定義)。沒錯,書中繼續描述被嵌入的文件能夠是.h文件,也一樣能夠是.cpp文件。可是當我在eclipse for c++環境裏驗證的時候卻打臉了,讓我一度懷疑是否是不能#include .cpp。vim
eclipse中在鏈接的那一步報錯了,以下:
數據結構
並無認真看eclipse中報錯內容的我在vim中一頓操做驗證結果明明能夠引入cpp的啊。上半部分是include .h的測試,下半部分是include .cpp的測試,均可以看出在生成.o文件也就是編譯生成目標代碼並沒啥錯,就在鏈接步驟引入.h的卻報錯,引入.cpp卻正常(這結果與在eclipse中恰好相反啊),這不由讓我思考了起來,哦發現了,在命令行中我是用命令指定編譯哪一個cpp文件,在引入.h的test.cpp測試中我只編譯了test而沒有編譯也沒鏈接point.cpp,因此鏈接時候找不到函數地址就很正常了(能夠注意到它報的錯是undefined,而eclipse中報的是duplicate,這就是區別...)
eclipse
回到eclipse,往上翻錯誤,看到eclipse好像是把我項目底下全部cpp都給編譯了,一看果真是...emmm make all。其實編譯就編譯吧也沒有啥影響最後別鏈接那些我沒用的就行,可是能夠看到這個真的是linker 了all啊..函數
因爲我在main.cpp中include了6文件夾的Point.cpp,這就至關於把6文件夾下的Point.cpp編譯了兩次(產生了兩個關於point.cpp的符號表,關於什麼是符號表,就是把程序中各個標識符名稱和它們在各段中的地址關聯起來的數據結構,見下圖)。而後在鏈接的時候,是將各個編譯單元的目標文件和運行庫當中被調用過的單元加以合併,通過合併後不一樣編譯單元代碼段和數據段就分別合併到一塊兒,與此同時,各個目標文件的符號表也能夠被綜合起來,鏈接最後符號表的每一個條目都必須有肯定的地址。然而eclipse鏈接報錯就報錯在符號表的函數地址應該是什麼,main中所引用的Point.cpp和6文件夾的Point.cpp是一個東西,但卻在生成.o文件時候符號表中的Point類的各個函數各自有了地址。學習
符號表可以被正確綜合的一個前提是,對於同一個符號,只在恰好一個編譯單元中有定義,而在其餘編譯單元中是未定義的。之因此有這個要求是由於合併後符號表中各個符號的地址須要根據該符號在有定義的編譯單元中的相對地址來肯定。若在多個編譯單元中同一個符號都有定義地址,那麼它的地址將無所適從,就會出現符號定義衝突的鏈接錯誤。因此能夠看到eclipse給出的錯誤提示是"duplicate symbol".測試
其中形如__ZN5...的名字是函數名,在符號表中函數並不僅以它在源程序中的名字命名,函數在符號表中的名字至少包括源程序的函數名和參數表類型信息。由於函數能夠重載,因爲符號表中沒有專門的類型信息,參數表信息只能在名字中有所體現,不然在目標文件中沒法對函數名相同單參數不一樣的函數加以區分。look,其中move函數就是我point類中定義的一個成員函數,剩下的都是構造函數(我定義的+類中默認的其餘構造)或析構函數把。因此,看來在eclipse中要非想引用cpp文件就要本身重寫eclipse中的make文件咯,另外還須要認真看報錯咯,不能一頓盲猜想。命令行
tip:若是5和6下的point.cpp都定義過相同標識符的成員,那麼在鏈接的時候也會報錯duplicate,看來在鏈接的時候並不會因所在文件夾不一樣就有區分,由於鏈接要肯定每一個標識符有惟一地址3d