在正式进入C++前,我们需要先了解了解C++。顾名思义,C++是基于C的一种编程语言,相较于C,C++写出来的代码更简洁,有时候C需要几百行代码,而C只需要几十行就可以解决,C++也很好的解决了C中存在的一些问题,例如:命名冲突。 C++的命名空间就能很好的解决这个问题。
在C语言中,我们定义的变量不能是库里有的,例如 int printf 就不能这么定义,因为printf是库的函数,这样定义变量就会命名冲突。
上图就很好的展示了这个错误。那库那么多,我们怎么保证当我们新加了一个头文件时,不会形成命名冲突呢?万一这个命名冲突又很多该怎么办?要全部改掉吗? 完全不需要,C++的命名空间可以完美解决这个问题。
定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
例:
namespace Eve //命名空间的名字
{
//命名空间的成员
int a=10;
int b=20;
char d='a';
} //注意这里没有分号
命名空间的成员可以是变量,函数,类型等; 命名空间可以嵌套定义; 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中; ps:一个工程中的test.h和上面test.cpp中两个N1会被合并成一个。
使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染。
域分为: 1.类域; 2.命名空间域; 3.全局域; 4.局部域; 它们的访问顺序一般是:局部域->全局域->展开的命名空间域 or 指定访问的命名空间域
作用域限定符:“::”(即两个冒号);
使用格式:命名空间的名字::成员名
注:若::前是空白,则访问的是全局的成员。
例:
namespace Eve
{
int a=10;
char b='a';
}
int main()
{
printf("%d %c\n",Eve::a,Eve::b); //访问命名空间内的成员
return 0;
}
using可以理解为展开,展开后的命名空间或是命名空间中的成员将暴露在全局域下。
例:
namespace Eve
{
int a=10;
int b=20;
}
using Eve::a; //展开命名空间中的成员a,注意后面有分号
int main()
{
printf("%d\n",a); //因为a已经展开了,所以可以直接使用
return 0;
}
例:
namespace Eve
{
int a=10;
int b=20;
}
using namespace Eve; //展开整个命名空间,注意后面有分号
int main()
{
printf("%d\n",a); //因为a已经展开了,所以可以直接使用
return 0;
}
访问嵌套的命名空间的成员时:
int a = 0;
namespace Eve
{
int a = 1;
}
//using namespace Eve;
int main()
{
int a = 2;
printf("%d\n", a);
printf("%d\n", ::a);
printf("%d\n", Eve::a);
return 0;
}
打印结果是什么呢?
如图所示:第一个printf 访问的是局部变量 第二个printf 访问的是全局变量; 第三个printf 访问的是命名空间Eve里的a。
using namespace std; 上面这句代码是展开标准库(展开前要包含头文件<iostream>),但不能随意展开,有一定的风险,平常练习可以用用,做项目时建议不要展开。 还有一些我们常用的可以展开,比如cout,cin,endl等,这样更便捷。