在c++中,变量,函数和类都是大量存在的,这些变量,函数和类的名称都存在与全局作用域中,可能会导致很多冲突,命名空间就是对标识符名称进行本地化,避免命名冲入或命名污染
1.命名空间使用关键字namespace定义:
namecapce 接一个命名空间的名字,后面再接一对{ },{ }内是命名空间的成员, 例如:
namespace N
{//命名空间中可以定义变量、函数、类型
int a;
double b;
int max_(int a, int b)
{
return a > b ? a : b;
}
struct S
{
char c;
int d;
};
}
命名空间可以嵌套
namespace N
{//命名空间中可以定义变量、函数、类型
int a;
double b;
int max_(int a, int b)
{
return a > b ? a : b;
}
struct S
{
char c;
int d;
};
namespace T//嵌套定义命名空间 T
{
int sub(int left, int right)
{
return left - right;
}
}
}
同一个工程中运行同时存在多个相同名称的命名空间,编译器最终会合成一个汇总的命名空间
2.命名空间的使用方式
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
namespace N
{//命名空间中可以定义变量、函数、类型
int a;
double b;
int max_(int a, int b)
{
return a > b ? a : b;
}
struct S
{
char c;
int d;
};
}
int main()
{
cin >> a;//编译器会报错,a为为声明标识符
return 0;
}
正确的使用方法:
(1)加命名空间名称及作用域
//对上面代码定义的命名空间N,这样使用可行
int main()
{
cin >> N::a ;
cout << N::a;
return 0;
}
(2)使用 using 命名空间名称::成员 将成员引入(只能使用命名空间被引入的成员)
//对上面定义的命名空间N,可以这样使用
using N::a;//a是一个变量
using N::S;//而S是一个类型
int main()
{
N::S s;//用命名空间的S自定义类型创建对象 :s
cin >> s.d >> a;
//cout << max_(s.d, a); 报错,max_未定义标识符
return 0;
}
(3)使用 using namespace 命名空间名称 的方式将整个命名空间引入
//对上面定义的命名空间N,可以这样使用
using namespace N;
int main()
{
S s;//用命名空间的S自定义类型创建对象 :s
cin >> s.d >> a;
cout << max_(s.d, a);
return 0;
}
3.std命名空间
std是c++标准库的命名空间,c++标准库的定义和实现都放在这个命名空间中,其中cout是定义在其中的ostream类(输出流)的对象,cin是定义在其中的istream类(输入流)的对象。
std命名空间的使用惯例:
std是C++标准库的命名空间,如何展开std使用更合理呢?
(1). 在日常练习中,建议直接using namespace std即可,这样就很方便。
(2). using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式。
如:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
//using namespace std;
namespace N
{
int cout;
}
using namespace N;
int main()
{
std::cin >> cout;//使用std中的cin输入 N当中的cout
std::cout << cout;//使用std中的cout输入 N当中的cout
return 0;
}