玩转C++名字空间
来源:互联网 发布:网络访谈节目 编辑:程序博客网 时间:2024/06/13 14:57
一、概要
名字空间是一种描述逻辑分组的机制。也就是说,如果有一些声明按照某种准则在逻辑上属于同一个集团,就可以将它们放入同一个名字空间,以表明这个事实。名字空间就是为了表示逻辑结构。同时也避免了名字冲突。
名字空间的声明和定义:
namespace namespace-name {}
PS:只有名字空间的声明定义与函数的定义后是不用分号;的,其余的都是要带分号的。
二、使用声明和使用指令
int main() {std::cout << "Hello World" << std::endl;std::cout << "Come On" << std::endl;return 0;}
如果像上面那样写,很令人厌烦。有两种方式可以解决这种烦恼。
(1)使用声明:
int main() {using std::cout;using std::endl;cout << "Hello World" << endl;cout << "Come On" << endl;return 0;}
使用声明,可以声明你想要的东西。
(2)使用指令
int main() {using namespace std;cout << "Hello World" << endl;cout << "Come On" << endl;return 0;}
使用指令,则把该名字空间下的所有名字都变成可用的。
全局性的使用指令是一种完成转变的工具,在其他方面最好避免使用。在一个名字空间里的使用指令是一种名字空间的组合工具。在一个函数里可以安全地讲使用指令作为一种方便的记法方式。
三、名字空间的组合
namespace Stack {void create();void push(char *data);char *pop();int length();} //在其他地方实现。namespace Employee {using namespace Stack;void init() {create();}void insert(char *name) {push(name);}char* get_employee() {return pop();}}名字空间的组合也是一种设计,设计理念类似于类的组合。
四、多重界面
多重界面可以提供给用户不同的借口,而用户不用关心其底层是怎么实现的。
例子:
str1.h
#ifndef STR1_H_INCLUDED#define STR1_H_INCLUDEDnamespace My_String { void init(); int length(); void set_string(char *data); void print_string();}#endif // STR1_H_INCLUDED
str2.h
#ifndef STR2_H_INCLUDED#define STR2_H_INCLUDEDnamespace My_String { void init(); int length();}#endif // STR2_H_INCLUDED
实现:strImpl.cpp
#include "str1.h"#include <iostream>namespace My_String {char *buf = new char[200];}void My_String::init() { strcpy(My_String::buf,"hello world");}int My_String::length() { return strlen(My_String::buf);}void My_String::print_string() { std::cout << buf << std::endl;}void My_String::set_string(char *data) { char *tem = (char*)malloc(strlen(data) + 1); strcpy(tem,data); delete buf; buf = tem;}
str1.h和str2.h使用的都是My_String的名字空间,但提供给外界的接口是不一样的。
测试:
#include <iostream>#include "str1.h" //包含的是str1using namespace std;int main() { My_String::init(); char *pc = "my pc"; My_String::set_string(pc); cout << My_String::length() << endl; My_String::print_string(); return 0;}
#include <iostream>#include "str2.h"using namespace std;int main() { My_String::init(); char *pc = "my pc"; My_String::set_string(pc); //错误,str2没提供这个接口 cout << My_String::length() << endl; My_String::print_string(); //错误,str2没提供这个接口 return 0;}
五、无名名字空间与名字空间别名
有时,将一组声明包裹在一个名字空间里就是为了避免可能的名字冲突。这样做的目的只是保持代码的局部性,而不是为用户提供界面。
noname.h
namespace {int a;double f(){};}void g() {f(); }
无名名字空间有一个隐含的使用指令的。上面的代码相当于。
namespace $$${int a;double f(){};}using namespace $$$;void g() {f(); }但不能在noname.h之外使用到这个无名名字空间里的东西了。例如:
#include "noname.h"void h() {a = 5; //错误,a不是全局变量,已经被包含在无名的名字空间中了。}
如果名字空间的名字太长,我们可以给他取个别名。
例如:
namespace SomeOne_Union_Shit {char *shit;.....}namespace SomeOne = SomeOne_Union_Shit;SomeOne::shit = "hello";
六、组合与选择
namespace His_lib {void f() { cout << "his f" << endl; }void g() { cout << "his g" << endl; }}namespace Her_lib {void f() { cout << "her f" << endl; }void g() { cout << "her g" << endl; }}namespace My_lib {using namespace His_lib;using namespace Her_lib;using His_lib::f; //偏向His_lib的方式解析潜在的冲突using Her_lib::g;//偏向Her_lib的方式解析潜在的冲突void h() {f(); // his fg(); // her g}}
七、名字空间与重载,以及其开放性。
重载可以跨名字空间工作的。
namespace His_lib {void f(int i) { cout << "his f" << endl; }}namespace Her_lib {void f(char c) { cout << "her f" << endl; }}namespace My_lib {void g() {f(3); //his fchar c = 'a';f(a); //her f}}
名字空间是开放的。一个名字空间的定义可以分布到多个头文件和源代码文件里。名字空间的开放性使我们可以通过展示名字空间不同部分的方式,为不同种类的用户提供不同的界面。
head1.h
namespace His_lib {void f() ;}
head2.h
namespace His_lib {void g() ;}
如果你只是向在文件里实现原先名字空间中已经声明的函数,则最好在此之前用名字空间的名字去修饰使用His_lib::的方式。
#include "head1.h"namespace His_lib {void His_lib::ff() {} //编译错误,His_lib没有声明这个。void ff() {} //编译通过,在名字空间His_lib中引用了新的ff函数}
一个名字空间应该:
[1]描述了一个具有逻辑统一性的特征集合。
[2]不为用户提供对无关特征的访问,使用封装。
[3]不给用户强加任何明显的记述负担。
参考书籍《C++程序设计语言》
- 玩转C++名字空间
- C++——名字空间
- C 语言中的名字空间(namespace)
- 名字空间
- 名字空间
- 名字空间
- 名字空间
- 名字空间
- 名字空间
- 名字空间
- 名字空间
- 名字空间
- 名字空间
- 名字空间
- JAXB玩转命名空间
- 转 javascript中的模块和名字空间
- c语言标识符的名字空间和作用域
- C++:C++背景、名字空间、结构联合枚举、字符串类型
- 将表达式转换成逆波兰式
- HBase在淘宝主搜索的Dump中的性能调优
- Lua1.0使用与研究- globals.lua
- 陨石撞飞机游戏 DirectX版
- PHP新手入门
- 玩转C++名字空间
- 游鱼海上跳DirectX版
- Java中的数字基本运算和精度问题
- SQLite 和 ContentProvider的使用
- bind()
- 分享一段代码来实现对孩子的监督
- 程序员的艺术:排序算法舞蹈【视频】
- 2012.8.21 单词 A Spanish Robin Hood?
- 1>Project : error PRJ0019: 某个工具从以下位置返回了错误代码: "Moc'ing thread.h