命名空间的概念
概念: 在C /C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染, namespace关键字的出现就是针对这种问题的。
简单来讲就是为了在名称相同时可以正常使用这些名称,才出现命名空间的。
命名空间的定义
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对花括号{ } 即可,{ }中即为命名空间的成员。
方式一:普通的命名空间定义
namespace N1
{
int a;
int Add(int x, int y)
{
return x + y;
}
}
方式二:命名空间的嵌套定义
namespace N2
{
int a;
int b;
int Add(int x, int y)
{
return x + y;
}
namespace N3
{
int c;
int d;
int Sub(int x, int y)
{
return x - y;
}
}
}
方式三:同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
namespace N1
{
int a;
int Add(int x, int y)
{
return x + y;
}
}
namespace N1
{
int Mul(int x, int y)
{
return x * y;
}
}
实际上等同于:
namespace N1
{
int a;
int Add(int x, int y)
{
return x + y;
}
int Mul(int x, int y)
{
return x * y;
}
}
命名空间的使用 举例:
#include<iostream>
namespace N
{
int a = 10;
int b = 20;
int Add(int x, int y)
{
return x + y;
}
int Mul(int x, int y)
{
return x * y;
}
}
int main()
{
printf("%d\n", a);
return 0;
}
从编译器给我们的反馈,可以大致推测,当定义命名空间之后,如果直接使用该命名空间内的某个名称,实际上编译器是无法识别,或者说是无法找到这个名称的。
命名空间的正确使用方式
方式一:加命名空间的名称及作用域限定符
int main()
{
printf("%d\n", N::a);
return 0;
}
基本概念补充: 作用域:开始生效到失效的程序范围段 生命周期:指的是程序执行过程中该对象存在的一段时间。 两者比较: 作用域与生命周期是两个完全不同的概念。 在英文中,作用域用“scope”表示,生命周期则用“duration”表示。 作用域是一个静态概念,只在编译源程序的时候用到。 一个标识符的作用域指在源文件中该标识符能够独立地合法出现的区域。 生命周期则是一个运行时(Runtime)概念,它是指一个变量在整个程序从载入到结束运行的过程中存在的时间周期。 由于函数和数据类型是静态的概念,它们没有生命周期的说法,它们从编译、程序的运行到结束整个过程是一直存在的。
方式二:使用using引入命名空间的成员
using N::b;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}
方式三:使用using namespace 命名空间名称引入,将所有名称全展开
using namespace N;
int main()
{
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
这种方式的好处:全展开,使用方便 坏处:库中的内容全部展开,若定义与库中名称相同的名称时,就会冲突了(也就是容易造成命名污染)
注意:如果是我们平时在学习C++做练习时,就不用过多考虑这个坏处,直接使用就好。 只有当我们真正参与到大型C++开发项目中,需要在意这个问题。
#include<iostream>
using std::cout;
using std::endl;
int main()
{
cout << "hello world!" << endl;
int i = 1;
double d = 1.111;
cout << i << endl;
cout << d << endl;
return 0;
}
|