作者james732 (好人超)
站內C_and_CPP
標題Re: [問題] 新手請較.cpp、.h跟副程式放置的問題
時間Tue Dec 29 12:38:56 2009
要先知道「在一個 a.cpp 裡,#include "file"」會做的是什麼事情
事實上,它就只是把 "file" 這個檔案的「所有內容」原封不動的貼到 a.cpp 裡
你的情況很簡單:codeblocks 所做的事情類似
1. 自動幫你編譯專案裡所有的 .cpp 檔變成 object file
g++ main.cpp -o main.o <=== 把 main.cpp 編譯成 main.o,OK
g++ func.cpp -o func.o <=== 把 func.cpp 編譯成 func.o,OK
2. 在編譯後,嘗試把這些 object file 連結成一個可執行檔
g++ main.o func.o main.exe <=== 在這個時候出事,兩個 object 的函式重覆
也就是你的 func.cpp 與 main.cpp 都會被編譯過
但是你的 main.cpp 裡又有 func.cpp 裡的「所有內容」
就像你把 func.cpp 整個複製貼上到 main.cpp 裡
編譯的時候(其實是link的時候)就會發現函式都有兩份的定義了
而 .h 檔並不會被編譯,只是單純的藉由 #include 被貼到 .cpp 檔裡
所以如果你改成 func.h 的話,最後真正被編譯的只有 main.cpp
因此不會有重覆定義的問題
當然你不該這麼寫,因為如果你又寫了另一個 xyz.cpp
include 了 func.h 之後,就會發現重覆定義又來敲門了
一個原則是, .h 檔本來就是被拿來貼上的
哪些東西應該"被貼上",諸如 class、struct、function 的 declare
原因很簡單,沒有這些東西的話,你根本沒辦法使用該 class 或 function
.h 不該有任何 definition,譬如變數的宣告或者函式的實體
所有的 definition 都該寫在 .cpp 檔裡,各別被編譯後,再被 link 起來
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.117.171.46
※ 編輯: james732 來自: 140.117.171.46 (12/29 12:40)
※ 編輯: james732 來自: 140.117.171.46 (12/29 12:46)
推 ljhgc:不然就是func.cpp這個檔案不要編譯就好了...?! 12/29 13:00
→ ljhgc:去func.cpp屬性頁裡面,把"從組件排除"改成yes... 12/29 13:01
→ ljhgc:另外, .h裡頭是可以做變數的宣告的 用extern就ok了 12/29 13:03
→ james732:是沒錯 不過 .cpp 檔本來就是要拿來編譯的 12/29 13:04
→ ljhgc:只是請記的在對應的.cpp裡 要去宣告此變數!!! 12/29 13:04
→ james732:在一個專案裡放一些"不編譯的cpp"還挺怪的...XD 12/29 13:04
→ ljhgc:是挺怪的,我第一次看的大型專案裡面 就擺了一堆"不"編譯的 12/29 13:06
→ ljhgc:當時第一次接觸到 看的有些霧煞煞的 12/29 13:06
推 ledia:設計得不好, 的確很容易看起來霧煞煞 12/29 13:11
推 cjoe:謝謝你的回覆!! 我懂了 12/29 15:26
推 legnaleurc:是喔 ... 我有時候會放不被編譯的 cpp 耶 XD 12/29 22:23
→ legnaleurc:不同平台就換不同的 cpp, header 共用一份這樣 12/29 22:24
推 VictorTom:推樓上, 的確有的code放在那邊是某些project setting下 12/29 22:26
→ VictorTom:不編譯的, 以我們家driver來說, XP / Vista / Linux都各 12/29 22:26
→ VictorTom:自會有編與不編的東西, 甚至是對應不同HW也有編與不編的 12/29 22:27
→ VictorTom:檔案, 端看不同build的makefile怎麼寫:) 12/29 22:27
推 sunneo:我也覺得放不同平台的src有相對的好處 12/29 22:31
→ sunneo:比如說我們不必被preprocessor的符號疑惑 12/29 22:31