【c++笔记一】"名字空间"(namespace)
2015-01-21 19:28
316 查看
2015年1月21日晴
寒假第一天,程序猿的第一天,减肥的第一天(瘦了两斤,鼓掌
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/proud.gif)
)
学要有所得,既然今天学了一天,是该好好整理一下今天所学的内容。
菜鸟一枚,如有bug还望指点一二。
-------------------------------------------------------华丽的分割线---------------------------------------------------------------
回到程序世界,一段程序中,可能有两个变量需要用到sum这个名字,除了改写成不同的sum(sum1或sum2)之外,我们还有什么方法呢?
啰嗦这么多,终于扯到namespace(名字空间)上来了。
先给大家看一段最简单的c++程序,一定是每个初学者都会看到的代码:
一个是一班的,一个是二班的。我们从逻辑上把他们放在了不同的两个班级中。
一班、二班就是我们定义的两个逻辑单元。
通过加上名字空间(一班或者二班),我们就能有效的区分,避免了同名带来的名字冲突。
2.我们要使用名字空间的时候,可以用 "::"这个符号(下面我们会讲到)
运行这个程序你会发现,输出是不同的结果:
![](http://img.blog.csdn.net/20150121201733996?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvem15b3Vrb253/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
由此我们可以知道名字空间的定义方法了:
namespace 空间名{...}
运行结果同上,节省空间不展示了。
这就是我们所说的名字空间的合并,只要名字空间一样无论你在哪里定义,最后都会合并在一起。
行不行,写出来就知道了。
用法就是在你要使用的变量或者函数名前加上“名字空间名 ::”,如“Class1::”
具体用法是这样:using namespace + 空间名;
写段代码看看怎么用:
因为我们使用了指令了using,把Class1这个名字空间解放出来了。也就是说从main函数一行之后凡是调用Class1名字空间里面的东西都可以省略前面的;;作用域限定符。
这也就是为什么使用了using namespace std 之后,cout和endl之前可以不用加上std::啦。
那又人或说了,既然这么方便那我以后就直接这么用吧。可是还有一点需要注意的地方。
如果main函数里面我这样写:
![](http://img.blog.csdn.net/20150121211704530?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvem15b3Vrb253/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
编译器提示说show()是有歧义的。
所以使用using的时候,会把你划分的逻辑单元的围墙推倒(比喻一下),名字冲突的问题再一次产生,也就失去了我们使用名字空间的意义。
所以个人建议这种方法最好不用。
具体看程序(前面因为一样的就省略):
虽然一开始你告诉编译器我使用的是Class1的名字空间,但是我任性的要使用Class2里面的show,编译器只好听你的。
这种方法容易让人产生误导,最好还是怪怪使用方法一比较靠谱些(除非你很懒)。
什么意思呢?请看程序
一句话,没有定义在任何名字空间的,都属于无名名字空间。
无名名字空间这么定义:namespace {..}
无名名字空间这样使用: ::变量名(或函数名)
发明c++的人还真是无聊
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
怎么个嵌套法?还是以程序说明(眼见为实)
怎么办?看来只好取个别名呢?怎么取呢?看如下代码:
寒假第一天,程序猿的第一天,减肥的第一天(瘦了两斤,鼓掌
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/proud.gif)
)
学要有所得,既然今天学了一天,是该好好整理一下今天所学的内容。
菜鸟一枚,如有bug还望指点一二。
-------------------------------------------------------华丽的分割线---------------------------------------------------------------
名字空间(namespace)
1.为什么需要名字空间呢?
假如你是月入上万的快递员蜀黍,有天你来到某某学校给小强送快递,可是一班有个小强,二班也有个小强。这小强怎么区分呢?回到程序世界,一段程序中,可能有两个变量需要用到sum这个名字,除了改写成不同的sum(sum1或sum2)之外,我们还有什么方法呢?
啰嗦这么多,终于扯到namespace(名字空间)上来了。
2.什么是名字空间?
从字面意思我们就能理解,这是一个用来存放名字的空间,可能你还不太懂,我们下面看程序就知道了。先给大家看一段最简单的c++程序,一定是每个初学者都会看到的代码:
#include <iostream> using namespace std; int main(){ cout<<"hello world"<<endl; return 0; }在第二行我们看见了我们看到了namespace这个单词,很多初学者肯定不知道这是干什么的。老师或许告诉你,不用管他干什么的,知道写上去就行了。读书最怕一知半解,我们接下来就来看看这到底是干什么的。
3.名字空间的作用:
(1)划分逻辑单元
比如,一班的小强和二班的小强不是同一个小强。一个是一班的,一个是二班的。我们从逻辑上把他们放在了不同的两个班级中。
一班、二班就是我们定义的两个逻辑单元。
(2)避免名字冲突
由上可知,小强这个名字冲突了。通过加上名字空间(一班或者二班),我们就能有效的区分,避免了同名带来的名字冲突。
4.怎样定义名字空间?
说了那么多,这到底怎么用呢?这里又有三个知识点:(1)名字空间定义
好吧,我们动手敲代码来区分这两个小强吧。#include <iostream> namespace Class1{ char xq[] = "我是一班的小强"; } namespace Class2{ char xq[] = "我是二班的小强"; } int main(){ std::cout<<Class1::xq<<std::endl; std::cout<<Class2::xq<<std::endl; return 0; }ps:1.cout和endl这两个属于std这个名字空间
2.我们要使用名字空间的时候,可以用 "::"这个符号(下面我们会讲到)
运行这个程序你会发现,输出是不同的结果:
由此我们可以知道名字空间的定义方法了:
namespace 空间名{...}
(2)名字空间合并
我们再看这样一段代码:#include <iostream> using namespace std; namespace Class1{ char xq[] = "我是一班的小强"; } namespace Class2{ char xq[] = "我是二班的小强"; } namespace Class1{ void show(){ cout<<xq<<endl; } } namespace Class2{ void show(){ cout<<xq<<endl; } } int main(){ Class1::show(); Class2::show(); return 0; }我们可以看到,show()这个函数和xq字符串并没有定义在一起,而是分开定义,但是同时属于一个名字空间。
运行结果同上,节省空间不展示了。
这就是我们所说的名字空间的合并,只要名字空间一样无论你在哪里定义,最后都会合并在一起。
(3)声明定义分开
学过c或者c++对的同学知道,声明和定义其实是可以分开的。先写声明,后定义。那名字空间可以吗?行不行,写出来就知道了。
#include <iostream> using namespace std; namespace Class1{ char xq[] = "我是一班的小强"; void show(); } // 声明 namespace Class2{ char xq[] = "我是二班的小强"; void show(); } //声明 int main(){ Class1::show(); Class2::show(); return 0; } namespace Class1{ void show(){ cout<<xq<<endl; } } // 定义 namespace Class2{ void show(){ cout<<xq<<endl; } } //定义运行结果同样一样,果然和我们以前学的声明定义一样,是可以分开的写的。
5.怎样使用名字空间?
既然我们已经定义好了名字空间了,怎么使用它呢?上面的代码我们已经使用了其中一种方法。接下来我给大家说三种方法:(1)作用域限定符(“ :: ”)
这个相信大家并不陌生了,因为上面我们已经用到了 。用法就是在你要使用的变量或者函数名前加上“名字空间名 ::”,如“Class1::”
(2)名字空间指令
其实这个我们之前也看到过,在最上面那段最简单的c++代码中的第二行:using namespace std;具体用法是这样:using namespace + 空间名;
写段代码看看怎么用:
#include <iostream> using namespace std; namespace Class1{ char xq[] = "我是一班的小强"; void show(){ cout<<xq<<endl; } } namespace Class2{ char xq[] = "我是二班的小强"; void show(){ cout<<xq<<endl; } } int main(){ using namespace Class1; show(); Class2::show(); return 0; }运行结果还是一样的,main函数的第二行调用的show()函数为什么是名字空间Class1里面的show呢?
因为我们使用了指令了using,把Class1这个名字空间解放出来了。也就是说从main函数一行之后凡是调用Class1名字空间里面的东西都可以省略前面的;;作用域限定符。
这也就是为什么使用了using namespace std 之后,cout和endl之前可以不用加上std::啦。
那又人或说了,既然这么方便那我以后就直接这么用吧。可是还有一点需要注意的地方。
如果main函数里面我这样写:
using namespace Class1; using namespace Class2; show();结果肯定就是编译器(我用的codeblocks)报错了。
编译器提示说show()是有歧义的。
所以使用using的时候,会把你划分的逻辑单元的围墙推倒(比喻一下),名字冲突的问题再一次产生,也就失去了我们使用名字空间的意义。
所以个人建议这种方法最好不用。
(3)名字空间声明
这种方法其实只是比第二种方法稍微改进一步。具体看程序(前面因为一样的就省略):
int main(){ using namespace Class1; using Class2::show; show(); return 0; }最后使用的是Class2里面的show。
虽然一开始你告诉编译器我使用的是Class1的名字空间,但是我任性的要使用Class2里面的show,编译器只好听你的。
这种方法容易让人产生误导,最好还是怪怪使用方法一比较靠谱些(除非你很懒)。
6.关于名字空间还需要注意的地方:
(1)无名名字空间
顾名思义,就没有名字的名字空间(我是无名氏,阿啦啦啦~~~~)什么意思呢?请看程序
#include <iostream> using namespace std; char my[] = "我是谁?"; int main(){ cout<<::my<<endl; return 0; }my是一个我们经常使用的全局变量,可能在我们没说名字空间之前你没有注意它的名字空间是什么吧?
一句话,没有定义在任何名字空间的,都属于无名名字空间。
无名名字空间这么定义:namespace {..}
无名名字空间这样使用: ::变量名(或函数名)
发明c++的人还真是无聊
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/titter.gif)
(2)名字空间的嵌套
我们知道,循环、函数有嵌套,那么名字空间也是有嵌套的。怎么个嵌套法?还是以程序说明(眼见为实)
#include <iostream> using namespace std; namespace hnsd{ namespace sjy{ namespace jsj{ char xq[] = "小强"; } } } int main(){ cout<<hnsd::sjy::jsj::xq<<endl; // 嵌套的名字空间需要一层一层的解析 return 0; }大部分用法和上面的一样,唯一要注意的地方就是,你嵌套了多少层,就需要解析多少层(也就是::符号要用几个啦,注意上下层次的关系不要弄错了)
(3)给名字空间取别名
从上面的代码我们可以看见,如果要用xq,前面还得加上“hnsd::sjy::jsj”一长串的名字空间,如果每次调用都写这么多,是不是太麻烦了一点?怎么办?看来只好取个别名呢?怎么取呢?看如下代码:
namespace name = hnsd::sjy::jsj; cout<<name::xq<<endl;这效果是一样一样的。很简单吧?
相关文章推荐
- 在Razor中如何引入命名空间?("import namespace in razor view")
- dom4j 子结点名字空间为 xmlns="" 解决办法
- 看"java编程思想"笔记
- 3.3.5 - [basic.scope.namespace] - 【基本.作用域.名字空间】
- "using namespace std"和"friend operator"
- 关于反射Assembly.Load("程序集").CreateInstance("命名空间.类")
- "flash加载flv,本地测试正常,上传至空间则失败"解决办法
- "系统化思维导论"读后的思考与笔记-第一章-问题
- 在看"美河制作-六个月成为网络专家"系列讲座时的心得笔记!!!
- 关于反射Assembly.Load("程序集").CreateInstance("命名空间.类")
- WTL学习笔记之"Enter"和"ESC"的一点小心得
- VC++中"using namespace std"的用处
- 读"Think in Java"后笔记(1)
- C++中命名空间"std"名字由来的思考
- "HOW TO: Create a Smooth Progress Bar in Visual C# .NET"的学习笔记
- CSDN重要产品"个人空间"新版预告 先睹为快!
- 看"java编程思想"笔记(5-6)
- 关于名字空间namespace
- namespace(C++名字空间)(2)
- ASP.NET学习笔记(5)--&quot;返回上一页&quot;功能的实现