C++ namespace
- 一、什么是 namespace
- 1.1 C语言标识符作用域的缺陷
- 1.2 namespace作用
- 二、namespace的定义
- 2.1 命名空间可以嵌套定义
- 小技巧
- 2.2 可定义重复的命名空间
- 三、namespace使用
- 3.1 命名空间名称+作用域限定符使用
- 3.2 using将命名空间中成员引入
- 3.3 使用using namespace将整个空间成员引入
一、什么是 namespace
1.1 C语言标识符作用域的缺陷
在C语言中因为项目需要会定义各种全局变量、函数等,我们也会调用C语言标准库提供给我们的各种函数,这将会导致我们变量名、函数名与标准库中的发生命名冲突。
#include <stdio.h>
#include <stdlib.h>int rand = 10; // 错误,与库函数rand命名冲突int main()
{printf("%d\n", rand);
}
1.2 namespace作用
在C++中通过namespace
来防止命名冲突,namespace
相当一件隐身衣,在namespace
中的变量、函数、类在namespace
外面是看不到,访问不到的,相当于不存在,所以也就不会发生命名冲突。即一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
二、namespace的定义
定义命名空间使用到namespace
关键字,后面跟命名空间的名字,然后接一对{ }即可,{ }中即为命名
空间的成员。空间名字可自定义命名
namespace kxl // kxl 为空间名字
{int rand = 10;int sum(int x,int y){return x+y;}struct Person{char name[10];int age;};
}
2.1 命名空间可以嵌套定义
namespace kxl // kxl 为空间名字
{int rand = 10;namespace kdl{int x = 0;int rand = 20;}
}
小技巧
命名空间嵌套层次太多时,使用里面的成员会很麻烦,可以对嵌套的命名空间取别名,这样使用起来会更加方便
#include <iostream>namespace kxl // kxl 为空间名字
{int rand = 10;namespace kdl{int x = 0;int rand = 20;namespace kzl{int rand = 30;int y = 5;}}
}namespace alias_kzl = kxl::kdl::kzl; // 别名int main()
{std::cout<< alias_kzl::y << std::endl;return 0;
}
2.2 可定义重复的命名空间
在一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间,但相同命名空间中的变量、函数、类不能重复定义
namespace kxl // kxl 为空间名字
{int rand = 10;
}namespace kxl // kxl 为空间名字
{// int rand = 20; 错误,相同命名空间变量名相同,编译器不知道合并哪一个randint x = 20;
}
最终编译器合并为
namespace kxl // kxl 为空间名字
{int rand = 10;int x = 20;
}
三、namespace使用
3.1 命名空间名称+作用域限定符使用
语法: 空间名称::标识符名
相当于告诉编译器去哪一个命名空间中找哪一个对象
namespace kxl // kxl 为空间名字
{int rand = 10;int x = 0;int y = 1;namespace kdl{int x = 20; int z = 100;}
}int main()
{printf("%d\n", kxl::rand); // kxl 为命名空间名称,:: 为作用域限定符, rand 为变量名printf("%d\n", kxl::kdl::x); // 访问kxl命名空间中的kdl里面的x变量return 0;
}
3.2 using将命名空间中成员引入
如果空间中某个对象经常使用,用3.1的方法比较繁琐,可以使用using
关键字将空间中某个对象引入,
即这个对象不隐身了,作用域为全局作用域
语法: using 空间名称::标识符名;
namespace kxl // kxl 为空间名字
{int rand = 10;int x = 0;int y = 1;
}using kxl::x;
// using kxl::rand; 不要将rand这样引入,否则rand和库函数rand发生命名冲突
int main()
{printf("%d\n",x);return 0;
}
3.3 使用using namespace将整个空间成员引入
使用using namespace将整个空间成员引入,即隐身衣失效了,空间中所有对象的作用域都是全局作用域,可以直接访问,但是与C++中引入命名空间初衷相矛盾,一般不建议这样用
语法:using namespce 空间名称;
namespace kxl // kxl 为空间名字
{int x = 0;int y = 1;
}using namespace kxl;int main()
{printf("%d\n", x); // x 相当于正常定义的全局变量,可以直接访问printf("%d\n", y);return 0;
}