[問題] Namespace的用法問題

看板C_and_CPP作者 (肥宅中的魯蛇)時間8年前 (2016/02/09 18:06), 編輯推噓6(6033)
留言39則, 3人參與, 最新討論串1/1
開發平台: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

02/09 18:15, , 1F
跟 namespace 無關, 你犯了在 .h 裡宣告全域變數的錯
02/09 18:15, 1F

02/09 18:15, , 2F
你把 namespace 拿掉一樣需要使用 extern 才行
02/09 18:15, 2F

02/09 18:16, , 3F
namespace 的概念就只是把「你的 i」「我的 i」「他的 i」
02/09 18:16, 3F

02/09 18:17, , 4F
給全部分開來, 變成用 You::i Me::i He::i 指名而已
02/09 18:17, 4F

02/09 18:29, , 5F
想請問一下 所以這樣會出錯原因是因為我已經在.cpp裡
02/09 18:29, 5F

02/09 18:30, , 6F
定義了一個全域變數 所以.h裡做宣告時後才會出錯嗎
02/09 18:30, 6F

02/09 18:35, , 7F
如果我.cpp都不寫任何code 單純在搬內宣告全域變數也
02/09 18:35, 7F

02/09 18:37, , 8F
會出錯 可是這樣子 duplicate是怎麼產生的呢?
02/09 18:37, 8F

02/09 18:38, , 9F
不好意思 上面打錯字 是指如果我單純在標頭宣告全域
02/09 18:38, 9F

02/09 18:38, , 10F
變數而不在.cpp定義變數 還是會出錯
02/09 18:38, 10F

02/09 19:43, , 11F
你一定有別的檔案也 #include "Supplement.hpp"
02/09 19:43, 11F

02/09 19:44, , 12F
因為 #include 只是複製貼上, 所以多個檔案裡都會有同樣的
02/09 19:44, 12F

02/09 19:44, , 13F
東西, 於是連結時連結器會不知道這名字到底要給誰
02/09 19:44, 13F

02/09 19:45, , 14F
加 extern 的意思就是告訴連結器說「這東西到時會在別處,
02/09 19:45, 14F

02/09 19:46, , 15F
但這個名字幫我留個記號起來」, 這樣連結器才知道你要用誰
02/09 19:46, 15F

02/09 21:26, , 16F
推 LPH66. 魯叔也補充一下自己的理解方式. 對 object/varia
02/09 21:26, 16F

02/09 21:27, , 17F
ble 做 extern 可以視為把本來是 definition 的 statement
02/09 21:27, 17F

02/09 21:27, , 18F
轉變成 declaration. 而原 po 遇到的錯誤極有可能就是 LPH6
02/09 21:27, 18F

02/09 21:27, , 19F
6 提到的多個 compilation unit 都 include 到該 definitio
02/09 21:27, 19F

02/09 21:27, , 20F
n, 等要 link 在一起的時候就出現重複的狀況了
02/09 21:27, 20F

02/09 21:35, , 21F
另再囉嗦幾句離題一下. IMHO, extern 能不用就不用. 用在 o
02/09 21:35, 21F

02/09 21:35, , 22F
bject/variable 上就是 global variable. 用在 function 上
02/09 21:35, 22F

02/09 21:35, , 23F
跟脫褲子放屁差不多概念. 有人跟我說過後者有 "就地" 引入
02/09 21:35, 23F

02/09 21:36, , 24F
的概念. 魯叔說, 不想討罵還是乖乖的去 include 正確的 hea
02/09 21:36, 24F

02/09 21:36, , 25F
der 吧 XD
02/09 21:36, 25F

02/09 23:42, , 26F
但其實我沒有include其他header耶 因為我就只有supple
02/09 23:42, 26F

02/10 01:41, , 27F
Supplement.cpp, Supplement.hpp和main.cpp而已
02/10 01:41, 27F

02/10 01:51, , 28F
我發現把.cpp刪掉後就可以跑了可是我那檔案根本沒東西
02/10 01:51, 28F

02/10 01:54, , 29F
結案! Supplement.cpp 與 main.cpp 想必都有 include Suppl
02/10 01:54, 29F

02/10 01:54, , 30F
ement.h 吧 XD
02/10 01:54, 30F

02/10 02:09, , 31F
直接畫重點好了: 問題不是兩個 .cpp 去 include 同一個 .h,
02/10 02:09, 31F

02/10 02:09, , 32F
這是完全正常的. 而是該 header 的內容有問題 - 在 header
02/10 02:09, 32F

02/10 02:09, , 33F
裡面放了 i 的 definition. 所以那兩個各自去 include 該
02/10 02:09, 33F

02/10 02:09, , 34F
header 的 .cpp (or compilation unit to be more specific
02/10 02:09, 34F

02/10 02:09, , 35F
) 都乖乖的認份遵從 programmer 的指示, 對外主張自己擁有
02/10 02:09, 35F

02/10 02:10, , 36F
一份 i 的實體. 等到 link 的時候兩邊喬不攏就炸了啊 QQ
02/10 02:10, 36F

02/10 23:27, , 37F
哈我瞭解了 如果是這樣的話 那通常namespace寫法是
02/10 23:27, 37F

02/10 23:28, , 38F
把宣告和實作都寫在.h裡面而已 還是說分開寫啊
02/10 23:28, 38F

02/10 23:54, , 39F
namespace 只是分別名字而已, 其他的實作什麼的完全照常
02/10 23:54, 39F
文章代碼(AID): #1MkRePlT (C_and_CPP)