先来看一个C语言的例子:
下面这段代码是可以正常运行的.
#include
int rand = 0;
int main()
{
printf("%d \n", rand);
return 0;
}
但是,包含了一个头文件之后,甚至无法通过编译.
#include
#include
int rand = 0;
int main()
{
printf("%d \n", rand);
return 0;
}
根据报错信息来看,rand本来是stdlib
库中的一个库函数,但是这里我们也创建了一个叫做rand的变量,所以这里在执行printf
语句时,就无法辨别rand到底是哪个了.
假若有人在项目中恰好就将某个变量名或者函数名设置成了与库中一样的名字,可就惨了,因为C语言本身是没有办法自己去解决这个问题的,只能我们主动避免.
命名空间的定义:所以为了解决上述出现的情况,C++中出现了命名空间.我们可以主动将我们声明的变量和函数等都写入这个命名空间中:
#include
#include
/*
定义命名空间的格式:
namespace 命名空间的名字
{
....
}
*/
namespace Space
{
int rand = 0;
}
int main()
{
printf("%p \n", rand);
return 0;
}
注意:当我们想要访问的是命名空间内的变量或函数时,需要在变量/函数名之前加上
命名空间名字::
,否则就是到命名空间之外去寻找该变量/函数,例如:
#include
#include
/*
定义命名空间的格式:
namespace 命名空间的名字
{
....
}
*/
namespace Space
{
int rand = 0;
}
int main()
{
printf("%d \n", Space::rand);
return 0;
}
例如:在下面这段代码中,在命名空间之内定义了一个Add函数,假若我们就只写一个
Add(1,3);
,这样是会报错的,因为没有在其之前指明Space::
,所以编译器会默认到命名空间之外去找, 而在命名空间Space之外并没有Add函数,所以就报错.
#include
#include
namespace Space
{
int rand = 0;
void Add(int x, int y)
{
printf("%d ", x + y);
}
}
int main()
{
printf("%d \n", Space::rand);
Add(1, 3);
return 0;
}
修正方案:
#include
#include
namespace Space
{
int rand = 0;
void Add(int x, int y)
{
printf("%d ", x + y);
}
}
int main()
{
printf("%d \n", Space::rand);
Space::Add(1, 3);
return 0;
}
命名空间的嵌套以及访问
假如命名空间之内还有一个命名空间,我们应当如何去访问最里层命名空间里的内容呢?
例如:访问如下命名空间里的
Div
函数.
#include
#include
namespace Space // 外层
{
int rand = 0;
void Add(int x, int y)
{
printf("%d ", x + y);
}
namespace Space1 //里层
{
void Div(int x, int y)
{
printf("%d", x - y);
}
}
}
访问命名空间:方法一:加命名空间名称以及作用域限定符.
#include
#include
namespace Space
{
int rand = 0;
void Add(int x, int y)
{
printf("%d ", x + y);
}
namespace Space1
{
void Div(int x, int y)
{
printf("%d", x - y);
}
}
}
int main()
{
printf("%d \n", Space::rand);
Space::Space1::Div(1, 3);
return 0;
}
访问命名空间:方法二:使用using将命名空间某个成员引入
#include
#include
namespace Space
{
int rand = 0;
void Add(int x, int y)
{
printf("%d ", x + y);
}
namespace Space1
{
void Div(int x, int y)
{
printf("%d", x - y);
}
}
}
using Space::Space1::Div;
int main()
{
printf("%d \n", Space::rand);
Div(1, 3);
return 0;
}
访问命名空间:方法三:使用using namespace 命名空间名称 引入
#include
#include
namespace Space
{
int rand = 0;
void Add(int x, int y)
{
printf("%d ", x + y);
}
namespace Space1
{
void Div(int x, int y)
{
printf("%d", x - y);
}
}
}
//引入命名空间Space1
using namespace Space::Space1;
//引入命名空间Space
using namespace Space;
int main()
{
printf("%d \n", Space::rand);
Add(1, 3);
Div(1, 3);
return 0;
}
先来看看C++是如何输入和输出的吧!
#include
using namespace std;
int main()
{
int a = 0;
cout << "hello world" << endl;
cin >> a;
return 0;
}
注意:std是C++标准库的命名空间名称,C++将标准库的定义实现都放到了这个命名空间中,而这里的
cout
和endl
都是在std标准库中定义的,有了using namespace std;
语句,就可以直接访问该定义了,不需要我们再手动加上命名空间名称和作用域限定符了.
这里特别说明:
cout
进行输出时,必须包含iostream
头文件.cout
和cin
以及endl
都是包含在iostream
中的.std命名空间的使用惯例:
using namespace std
即可,这样就很方便。using namespace std
展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像std::cout
这样使用时指定命名空间 +using std::cout
展开常用的库对象/类型等方式。