[问题] Namespace的用法问题

楼主: a126040023 (肥宅中的鲁蛇)   2016-02-09 18:06:15
开发平台: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才不会出现错误。
作者: LPH66 (-6.2598534e+18f)   2016-02-09 18:15:00
跟 namespace 无关, 你犯了在 .h 里宣告全域变量的错你把 namespace 拿掉一样需要使用 extern 才行namespace 的概念就只是把“你的 i”“我的 i”“他的 i”给全部分开来, 变成用 You::i Me::i He::i 指名而已
楼主: a126040023 (肥宅中的鲁蛇)   2016-02-09 18:29:00
想请问一下 所以这样会出错原因是因为我已经在.cpp里定义了一个全域变量 所以.h里做宣告时后才会出错吗如果我.cpp都不写任何code 单纯在搬内宣告全域变量也会出错 可是这样子 duplicate是怎么产生的呢?不好意思 上面打错字 是指如果我单纯在标头宣告全域变量而不在.cpp定义变量 还是会出错
作者: LPH66 (-6.2598534e+18f)   2016-02-09 19:43:00
你一定有别的档案也 #include "Supplement.hpp"因为 #include 只是复制贴上, 所以多个档案里都会有同样的东西, 于是连结时连结器会不知道这名字到底要给谁加 extern 的意思就是告诉连结器说“这东西到时会在别处,但这个名字帮我留个记号起来”, 这样连结器才知道你要用谁
作者: fr3ak (fr3@K)   2016-02-09 21:26:00
推 LPH66. 鲁叔也补充一下自己的理解方式. 对 object/variable 做 extern 可以视为把本来是 definition 的 statement转变成 declaration. 而原 po 遇到的错误极有可能就是 LPH66 提到的多个 compilation unit 都 include 到该 definition, 等要 link 在一起的时候就出现重复的状况了另再囉嗦几句离题一下. IMHO, extern 能不用就不用. 用在 object/variable 上就是 global variable. 用在 function 上跟脱裤子放屁差不多概念. 有人跟我说过后者有 "就地" 引入的概念. 鲁叔说, 不想讨骂还是乖乖的去 include 正确的 header 吧 XD
楼主: a126040023 (肥宅中的鲁蛇)   2016-02-09 23:42:00
但其实我没有include其他header耶 因为我就只有suppleSupplement.cpp, Supplement.hpp和main.cpp而已我发现把.cpp删掉后就可以跑了可是我那档案根本没东西
作者: fr3ak (fr3@K)   2016-02-10 01:54:00
结案! Supplement.cpp 与 main.cpp 想必都有 include Supplement.h 吧 XD直接画重点好了: 问题不是两个 .cpp 去 include 同一个 .h,这是完全正常的. 而是该 header 的内容有问题 - 在 header里面放了 i 的 definition. 所以那两个各自去 include 该header 的 .cpp (or compilation unit to be more specific) 都乖乖的认份遵从 programmer 的指示, 对外主张自己拥有一份 i 的实体. 等到 link 的时候两边乔不拢就炸了啊 QQ
楼主: a126040023 (肥宅中的鲁蛇)   2016-02-10 23:27:00
哈我了解了 如果是这样的话 那通常namespace写法是把宣告和实作都写在.h里面而已 还是说分开写啊
作者: LPH66 (-6.2598534e+18f)   2016-02-10 23:54:00
namespace 只是分别名字而已, 其他的实作什么的完全照常

Links booklink

Contact Us: admin [ a t ] ucptt.com