玩转C++名字空间
2012-08-21 08:32
211 查看
一、概要
名字空间是一种描述逻辑分组的机制。也就是说,如果有一些声明按照某种准则在逻辑上属于同一个集团,就可以将它们放入同一个名字空间,以表明这个事实。名字空间就是为了表示逻辑结构。同时也避免了名字冲突。
名字空间的声明和定义:
PS:只有名字空间的声明定义与函数的定义后是不用分号;的,其余的都是要带分号的。
二、使用声明和使用指令
如果像上面那样写,很令人厌烦。有两种方式可以解决这种烦恼。
(1)使用声明:
使用声明,可以声明你想要的东西。
(2)使用指令
使用指令,则把该名字空间下的所有名字都变成可用的。
全局性的使用指令是一种完成转变的工具,在其他方面最好避免使用。在一个名字空间里的使用指令是一种名字空间的组合工具。在一个函数里可以安全地讲使用指令作为一种方便的记法方式。
三、名字空间的组合
四、多重界面
多重界面可以提供给用户不同的借口,而用户不用关心其底层是怎么实现的。
例子:
str1.h
str2.h
实现:strImpl.cpp
str1.h和str2.h使用的都是My_String的名字空间,但提供给外界的接口是不一样的。
测试:
五、无名名字空间与名字空间别名
有时,将一组声明包裹在一个名字空间里就是为了避免可能的名字冲突。这样做的目的只是保持代码的局部性,而不是为用户提供界面。
noname.h
无名名字空间有一个隐含的使用指令的。上面的代码相当于。
如果名字空间的名字太长,我们可以给他取个别名。
例如:
六、组合与选择
七、名字空间与重载,以及其开放性。
重载可以跨名字空间工作的。
名字空间是开放的。一个名字空间的定义可以分布到多个头文件和源代码文件里。名字空间的开放性使我们可以通过展示名字空间不同部分的方式,为不同种类的用户提供不同的界面。
head1.h
head2.h
如果你只是向在文件里实现原先名字空间中已经声明的函数,则最好在此之前用名字空间的名字去修饰使用His_lib::的方式。
总结:
一个名字空间应该:
[1]描述了一个具有逻辑统一性的特征集合。
[2]不为用户提供对无关特征的访问,使用封装。
[3]不给用户强加任何明显的记述负担。
参考书籍《C++程序设计语言》
名字空间是一种描述逻辑分组的机制。也就是说,如果有一些声明按照某种准则在逻辑上属于同一个集团,就可以将它们放入同一个名字空间,以表明这个事实。名字空间就是为了表示逻辑结构。同时也避免了名字冲突。
名字空间的声明和定义:
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_INCLUDED namespace 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_INCLUDED namespace 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" //包含的是str1 using 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 f g(); // 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 f char 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++中的enum的名字空间
- c++名字空间
- c++ 静态类成员函数(static member function) vs 名字空间 (namespace)
- C++名字空间详解
- C++名字空间
- 关于C++名字空间
- C++中的名字空间
- C++学习笔记---内部类与名字空间
- Namespaces (C++的名字空间)
- C++名字空间详解
- 关于c++名字解析的一个问题:名字空间污染
- C++名字空间详解
- C++ Coding Standards:名字空间和模块
- C和C++中的名字空间和作用域
- C++初级主题--名字空间域和类域
- c++笔记01---c++ 简介,g++ 编译器,名字空间,结构,联合,枚举
- c++名字空间
- C++名字空间的主要用法示例
- [C++ rudiment]名字空间 namespace
- 对C++的基本认识之名字空间域