即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

C++命名空间

编程语言 xuptacm 28℃ 0评论
本文目录
[隐藏]

1.命名空间的定义

► 大型应用程序经常使用来自不同厂商的开发库,几乎不可避免会使


用相同的名字,也就是说一个库中定义的名字可能与其他库中的名


字相同而产生冲突,使得程序员不能组合各自独立的开发库到一个


程序中。


► 命名空间是用来限定名字的解析和使用范围的,它是C++开发大型


程序的工具之一。

► 命名空间的原理是将全局作用域划分为一个一个的命名空间,每个


命名空间是一个独立的作用域,在不同命名空间内部定义的名字彼


此之间互不影响,从而有效的避免了命名空间污染。

2.► 1. 定义命名空间

► 命名空间的定义形式为:


► 命名空间可以在全局作用域或其他命名空间内部定义,但不能在函


数、结构体或类内部定义,且要保证命名空间之间不会出现名字冲


突。

namespace 命名空间名 { {
……
} }

► 在命名空间作用域内,可以包含以下内容:


► ① 变量、对象以及它们的初始化。


► ② 枚举常量。


► ③ 函数声明以及函数定义。


► ④ 类、结构体声明与实现。


► ⑤ 模板。


► ⑥ 其他命名空间。

namespace A A{ { // 定义命名空间A A
const  int  PI= = 3.1415926; ; //const 常量
enum  tagDAYS{ { MON, , TUE, , WED, , THU, , FRI, , SAT, , SUN }; // 枚举常量
int i i, ,j j, ,k k= = 10; ; // 变量及变量的初始化
string str, , str2 ("hello"); // 对象及对象的初始化
int  max( ( int x x, , int y y ); // 函数声明
int  min( ( int x x, , int y y ){ return x x> > y?x: :y y ;} // 函数定义
template< < typename T T> > // 函数模板
int  compare( ( const T T& & v1, , const T T& & v2 ){ return  v1 == v2 ;}
template< < class T T> >  class  TComplex{ { // 类模板
public: :
TComplex (){}
void  setdata( ( T a, , T b ){x x= =a a; ;y y= =b b ;}
private: :
T r, ,i i; ;
};
namespace B B{ { // 嵌套的命名空间
int i i, ,j j, ,k k; ;
} }
} }

► (1)每个命名空间是一个作用域


► 定义在命名空间中的实体称为命名空间成员。命名空间中的每个名


字必须是该命名空间中的唯一实体,不同命名空间可以具有同名成


员。

namespace  A{ // 定义命名空间A A
int  fun,j;
int  fun(){return 10;} //错误,同一命名空间不能有相同的名字
} }
namespace  B{ // 定义命名空间B B
int  fun,j; //正确,不同命名空间可以有相同的名字
} }

► 在命名空间中定义的名字可以被命名空间中的其他成员直接访问,


命名空间外部的代码必须指出名字定义在哪个命名空间中,即作用


域运算符限定命名空间,形式为:


► 例如:

命名空间 :: 成员名
namespace  A{ // 定义命名空间A A
int  i=10;
void  output1(){cout<// 同一命名空间种直接引用成员i i
} }
void  output2(){cout<// 引用命名空间限定成员 A::i

► (2)命名空间可以是不连续的


► 命名空间可以在几个部分中分开定义,即命名空间是累积的。一个


命名空间可以分散在多个文件中。

namespace  A{ // 新创建一个命名空间A A
int  i;
} }
namespace  B{ // 新创建一个命名空间B B
int  i,j;
} }
namespace  A{ // 合并到前面的命名空间A A
int  j;
} }

► (3)接口和实现分离


► 命名空间可以不连续意味着可以做以下事情:


► 命名空间成员如果是类,可以将作为类接口的函数声明和对象


声明放在头文件中,使用这些命名空间成员的文件可以包含这


些头文件。


► 命名空间类成员的定义可以放在单独的源文件中。

► 例:

// complex.h  类接口放在头文件中
namespace A{ // 定义命名空间A A
class complex{
public:
complex(){}
void setdata(double a,double b);
private:
double r,i;
};
} }
// complex.cpp  类实现放在源文件中
namespace A{ // 合并到头文件中的A A
void complex::setdata(double a,double b){r=a;i=b;}
} }

► (4)定义命名空间成员


► 在命名空间内部定义的函数可以使用同一命名空间中定义的名字。


► 也可以在命名空间外部定义命名空间成员:

namespace A{ // sub 中直接使用 complex 类型
complex sub(complex& c1,complex& c2);
} }
A::complex A::sub(complex& c1,complex& c2);
{ { complex c;
c.setdata(c1.getr()+c2.getr(),c1.geti()+c2.geti());
return c;
} }

► (5)全局命名空间


► 定义在全局作用域的名字(任何类、函数或命名空间外部声明的名


字)是定义在全局命名空间中的。全局命名空间存在于每个程序中,


是隐式的。


► 可以用作用域运算符引用全局命名空间的成员:

int i=10; // 全局作用域
namespace A{ // 命名空间A A
void output(){ cout<<::i; } // 使用全局作用域成员i i
} }

► (6)嵌套命名空间


► 嵌套命名空间中的名字遵循名字规则:外围命名空间中声明的名字


被嵌套命名空间中同一名字的声明所屏蔽。

namespace outer{ // 外围命名空间
int i;
namespace inner{ // 嵌套命名空间
void f(){i++;}  // 使用的是 outer::i
int i; // 嵌套命名空间中的i i 屏蔽了 outer::i
void g(){i++;}  // 使用的是 inner::i
void h(){outer::i++;} // 使用的是 outer::i
} }
} }

► 2. 未命名的命名空间


► 定义命名空间时如果没有给出命名空间名字,称为未命名的命名空


间,定义形式为:

namespace  {
……
} }

► (1)未命名的命名空间中定义的名字可以直接使用,没有命名空


间名字来限定它们。


► (2)未命名的命名空间可以在给定文件中不连续,但不能跨越文


件,每个文件有自己的未命名的命名空间。本质上在一个文件中所


有未命名的命名空间会被系统用同一个标识符代替,且区别于其他


文件的标识符。

► 例:

namespace { int i; } // 假定未命名的命名空间标识为 unique
void f(){ i++; } //unique::i++
namespace A{
namespace {
int i,j; //A::unique::i 和 A::unique::j
}
void g(){ i++; } //A::unique::i++
} }
using namespace A;
void h(){
A::i++; //A::unique::i++
j++; //A::unique::j++
} }

► (3)未命名的命名空间专门用于声明局部于文件的实体。


► (4)未命名的命名空间中定义的名字只在包含该命名空间的文件


中可见。如果另一文件包含一个未命名的命名空间,两个命名空间


不相关,可以定义相同名字的实体。

转载请注明:CodingBlog » C++命名空间

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情