看板 C_and_CPP 關於我們 聯絡資訊
開發平台:Xcode7.2 小弟最近開始接觸到namespace這個東西。由於對它不是很了解,只從書上大概了解他的 語法,我假設他的寫法跟class一樣是在.h做declaration 然後在.cpp做implementation 我看到很多書或是網站也都是這樣寫。但是我在.h對變數做宣告的時候,假如不加上 extern或static這兩個修飾詞的話都會出現編譯錯誤:duplicate symbol for architecture x86_64 想請教一下為什麼會這樣?他跟class之間有什麼差別嗎?除了不能實體化之外。或著說 在compile時候compiler處理他跟處理class是什麼不同的方式啊。 ex: __________Supplement.h____________ #ifndef Supplement_hpp #define Supplement_hpp #include <stdio.h> #include <iostream> #include <map> using namespace std; namespace MyNameSpace { int i; } #endif /*Supplement_hpp */ _____________main.cpp______________ #include <stdlib.h> #include "Supplement.hpp" using namespace std; int main(int argc, const char * argv[]) { cout << MyNameSpace::i << endl; } 上面這樣就會出現編譯錯誤。必須要把 int i 改成 extern int i才不會出現錯誤。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 122.116.30.40 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1455012377.A.BDD.html
LPH66: 跟 namespace 無關, 你犯了在 .h 裡宣告全域變數的錯 02/09 18:15
LPH66: 你把 namespace 拿掉一樣需要使用 extern 才行 02/09 18:15
LPH66: namespace 的概念就只是把「你的 i」「我的 i」「他的 i」 02/09 18:16
LPH66: 給全部分開來, 變成用 You::i Me::i He::i 指名而已 02/09 18:17
a126040023: 想請問一下 所以這樣會出錯原因是因為我已經在.cpp裡 02/09 18:29
a126040023: 定義了一個全域變數 所以.h裡做宣告時後才會出錯嗎 02/09 18:30
a126040023: 如果我.cpp都不寫任何code 單純在搬內宣告全域變數也 02/09 18:35
a126040023: 會出錯 可是這樣子 duplicate是怎麼產生的呢? 02/09 18:37
a126040023: 不好意思 上面打錯字 是指如果我單純在標頭宣告全域 02/09 18:38
a126040023: 變數而不在.cpp定義變數 還是會出錯 02/09 18:38
LPH66: 你一定有別的檔案也 #include "Supplement.hpp" 02/09 19:43
LPH66: 因為 #include 只是複製貼上, 所以多個檔案裡都會有同樣的 02/09 19:44
LPH66: 東西, 於是連結時連結器會不知道這名字到底要給誰 02/09 19:44
LPH66: 加 extern 的意思就是告訴連結器說「這東西到時會在別處, 02/09 19:45
LPH66: 但這個名字幫我留個記號起來」, 這樣連結器才知道你要用誰 02/09 19:46
fr3ak: 推 LPH66. 魯叔也補充一下自己的理解方式. 對 object/varia 02/09 21:26
fr3ak: ble 做 extern 可以視為把本來是 definition 的 statement 02/09 21:27
fr3ak: 轉變成 declaration. 而原 po 遇到的錯誤極有可能就是 LPH6 02/09 21:27
fr3ak: 6 提到的多個 compilation unit 都 include 到該 definitio 02/09 21:27
fr3ak: n, 等要 link 在一起的時候就出現重複的狀況了 02/09 21:27
fr3ak: 另再囉嗦幾句離題一下. IMHO, extern 能不用就不用. 用在 o 02/09 21:35
fr3ak: bject/variable 上就是 global variable. 用在 function 上 02/09 21:35
fr3ak: 跟脫褲子放屁差不多概念. 有人跟我說過後者有 "就地" 引入 02/09 21:35
fr3ak: 的概念. 魯叔說, 不想討罵還是乖乖的去 include 正確的 hea 02/09 21:36
fr3ak: der 吧 XD 02/09 21:36
a126040023: 但其實我沒有include其他header耶 因為我就只有supple 02/09 23:42
a126040023: Supplement.cpp, Supplement.hpp和main.cpp而已 02/10 01:41
a126040023: 我發現把.cpp刪掉後就可以跑了可是我那檔案根本沒東西 02/10 01:51
fr3ak: 結案! Supplement.cpp 與 main.cpp 想必都有 include Suppl 02/10 01:54
fr3ak: ement.h 吧 XD 02/10 01:54
fr3ak: 直接畫重點好了: 問題不是兩個 .cpp 去 include 同一個 .h, 02/10 02:09
fr3ak: 這是完全正常的. 而是該 header 的內容有問題 - 在 header 02/10 02:09
fr3ak: 裡面放了 i 的 definition. 所以那兩個各自去 include 該 02/10 02:09
fr3ak: header 的 .cpp (or compilation unit to be more specific 02/10 02:09
fr3ak: ) 都乖乖的認份遵從 programmer 的指示, 對外主張自己擁有 02/10 02:09
fr3ak: 一份 i 的實體. 等到 link 的時候兩邊喬不攏就炸了啊 QQ 02/10 02:10
a126040023: 哈我瞭解了 如果是這樣的話 那通常namespace寫法是 02/10 23:27
a126040023: 把宣告和實作都寫在.h裡面而已 還是說分開寫啊 02/10 23:28
LPH66: namespace 只是分別名字而已, 其他的實作什麼的完全照常 02/10 23:54