c++ 命名空间

来源:互联网 发布:java对齐输出 编辑:程序博客网 时间:2024/05/29 07:17

1 命名空间介绍
使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突。下面是一个简单的命名空间的例子:

namespace MyNames {int iVal1 = 100;int iVal2 = 200;}


 

这里有两个整型变量iVal1和iVal2被定义为MyNames 命名空间的组成部分。

 

2 命名空间的成员
命名空间的一个例子就是std,它是C++定义标准库的命名空间。为使用cout 流对象,你必需告诉编译器cout 已存在于std 名字空间中。为达到上述目的可以指定名字空间的名称和作用域限定操作符(::)作为cout 标识符的前缀。如下所示:

#include <iostream>int main() {std::cout << "hello";return 0;}



通过使用cout 对象将流文本输出到屏幕上来显示短信息。注意std 名字空间是如何出现在cout 对象名称前面的。


3 using namespace 语句
使用已在命名空间中定义的标识符的另一种方法是将using namespace 语句把需要使用到的命名空间包含进来,例如:

#include <iostream>using namespace std;int main() {cout << "hello";return 0;}


 

不仅cout 标识符不再需要std 前缀,而且在std 命名空间定义的其他任何标识符都是如此。下面示例显示了使用using
namespace 语句可能遇到的问题:

#include <iostream>namespace MyNames {int iVal1 = 100;int iVal2 = 200;}namespace MyOtherNames {int iVal1 = 300;int iVal2 = 400;}using namespace std;using namespace NyNames;using namespace NyOtherNames;int main() {cout << "hello";iVal1 = 100;return 0;}



当试图编译程序时,大多数均会提示相应的出错信息。因为在语句iVal1=100中,编译器并不知道程序所指的是iVal1的哪种版本。是在MyNames 中定义的iVal1,还是在MyOtherNames 定义的iVal1呢?编译器并没有办法识别。为了避免出现这种类型的问题,应该将程序改写如下,程序将会正确编译和执行:

#include <iostream>namespace MyNames {int iVal1 = 100;int iVal2 = 200;}namespace MyOtherNames {int iVal1 = 300;int iVal2 = 400;}int main() {std::cout << "hello";MyNames::iVal1 = 100;return 0;}



4 定义命名空间
一个命名空间可以包含多种类型的标识符,如下面所列:
1)变量名
2)常量名
3)函数名
4)结构名
5)类名
6)命名空间名
一个命名空间可以在两个地方被定义:在全局范围层次或者是在另一个命名空间中被定义(这样就形成一个嵌套命名空间)。如下所示:

#include <iostream>namespace NyNames {const int MAX_LENGTH = 100;int iVali = 100;long iVal2 = 200L;char cr = 'Z';int Add(int i, int j) {return i + j;}long Sub(long i, long j) {return i - j;}}int main() {std::cout << NyNames::Add(NyNames::MAX_LENGTH, NyNames::iVali);std::cout << NyNames::Sub(NyNames::iVal2, NyNames::cr);return 0;}


 

5 嵌套命名空间
命名空间可以在其他命名空间中被定义。在这种情况下,仅仅通过使用外部的命名空间作为前缀,一个程序仅可以引用外部命名空间中定义的标识符。要想引用内部命名空间定义的标识符,需要使用外部和内部命名空间名称作为前缀。

#include <iostream>namespace MyOutNames {int iVal1 = 100;int iVal2 = 200;namespace MyInnerNames {int iVal3 = 300;int iVal4 = 400;}}int main() {std::cout << MyOutNames::iVal1 << std::endl;std::cout << MyOutNames::iVal2 << std::endl;std::cout << MyOutNames::MyInnerNames::iVal3 << std::endl;std::cout << MyOutNames::MyInnerNames::iVal4 << std::endl;return 0;}


注意:

不能在命名空间的定义中声明(另一个嵌套的)子命名空间,只能在命名空间中定义子命名空间。也不能直接使用“命名空间名::成员名 ……”的方式,为命名空间添加新成员,而必须在命名空间的定义中添加新成员的声明。


6 无名命名空间
尽管给定命名空间的名称是有益的,但你可以通过在定义中省略命名空间的名称而简单地声明无名命名字空间,例如:

namespace {int iVal1 = 100;int iVal2 = 200;}


 

事实上,在无名命名空间中定义的标识符被设置为全局的命名空间,这几乎彻底破坏了命名空间设置的最初目的。基于这个原因,无名命名空间并未被广泛应用。


7 命名空间的别名
可以给命名空间取别名,它是已定义的命名空间的可替换的名称。通过将别名指定给当前的命名空间的名称,你可以简单地创建一个命名空间的别名。例如:

#include <iostream>namespace MyNames {int iVal1 = 100;int iVal2 = 200;}namespace MyAlias = MyNames;int main() {std::cout << MyAlias::iVal1 << std::endl;std::cout << MyAlias::iVal2 << std::endl;return 0;}



8 命名空间综合举例
通过上面的学习我们了解了什么是命名空间以及命名空间的用途,也举了大量的例子说
明了命名空间的使用;但以上我们都是以单文件的形式说明命名空间的,然而我们知道C++
程序是由头文件和源文件组成的;例如我想在头文件中定义了一个命名空间,并且在命名空间
中定义了一个类,那么如何在源文件中实现这个类呢?

#ifndef TEST_H#define TEST_Hnamespace MyNames {class TestClass {public:void PrintVal();TestClass(int iVal);private:int m_iVal;};}#endif


 

#include <iostream>#include " Test7.h "namespace MyNames {TestClass::TestClass(int iVal) {m_iVal = iVal;}void TestClass::PrintVal() {std::cout << m_iVal << std::endl;}}


 

#include <iostream>#include " Test7.h "int main() {MyNames::TestClass rTest(800);rTest.PrintVal();return 0;}
原创粉丝点击