【C++】命名空间

目录

[1 命名空间的引入](#1 命名空间的引入)

[2 命名空间的定义](#2 命名空间的定义)

[3 标准命名空间std](#3 标准命名空间std)

头文件和std的关系

[4 命名空间的使用](#4 命名空间的使用)

[4.1 加命名空间名称及作用域限定符::](#4.1 加命名空间名称及作用域限定符::)

[4.2 使用using将命名空间中某个成员引入(最推荐)](#4.2 使用using将命名空间中某个成员引入(最推荐))

[4.3 使用using namespace +命名空间名称](#4.3 使用using namespace +命名空间名称)

[5 总结](#5 总结)


1 命名空间的引入

为了解决C语言中命名冲突问题,C++引入了命名空间:

rand()函数包含在C语言头文件stdlib.h里,为了解决这个问题,可以这样做:

2 命名空间的定义

命名空间里可以放任意的变量、函数、结构体等等

cpp 复制代码
namespace space2
{
	int a = 10;
	
	int add(int x, int y)
	{
		return x + y;
	}

	struct ListNode
	{
		struct SListNode* next;
		int val;
	};
	//...
}

命名空间的嵌套

cpp 复制代码
namespace s3
{
	int a = 10;
	namespace s4
	{
		int a = 20;
	}
}

命名空间s3和s4的变量a虽然同名,但并不会冲突!

命名空间的合并

cpp 复制代码
#include<iostream>
namespace s3
{
	int a = 10;
}

namespace s3
{
	int b = 20;
}

int main()
{
	std::cout << s3::b << std::endl;
    return 0;
}

上面的写法相当于:

cpp 复制代码
namespace s3
{
	int a = 10;
	int b = 20;
}

std是C++的标准命名空间 ,::是作用域限定符,下面会详细介绍。

3 标准命名空间std

标准命名空间std是C++标准库中定义的命名空间,用于包含一系列标准库提供的类、函数和对象。它提供了一种组织和封装代码的机制,以避免命名冲突,并将相关的实体进行逻辑上的分组。在程序中使用std命名空间,可以方便地使用标准库中的函数、对象等。

比如C++的标准输入cin输出cout,STL中的vector、sort、queue、stack等等都在std命名空间里。

头文件和std的关系

先来看一个C++输出hello world的程序:

cpp 复制代码
#include<iostream>
using namespace std;//标准命名空间std展开

int main()
{
	cout << "Hello World" << endl;
	return 0;
}

其中,iostream文件的包含以及标准命名空间std的展开都是缺一不可的,为什么呢?

头文件和std命名空间的关系是,头文件中的内容被包含在std命名空间中。这意味着,如果一个头文件没有使用任何命名空间,那么其定义的所有符号都位于全局作用域;如果一个头文件使用了命名空间std,那么其定义的所有符号都位于std命名空间中。

在C++标准库中,许多常用的函数、对象和类都被定义在std命名空间中,例如std::coutstd::vector等。因此,在使用这些函数、对象或类时,需要使用std::前缀来标识它们属于std命名空间。

需要注意的是,虽然大部分编译器在实现时并没有严格遵循C++标准,对于原来C语言的头文件,即使按照C++的方式来使用,即#include <cstdio>这种形式,那么符号可以位于命名空间std中,也可以位于全局范围中:

如果我们将C++的cstdio头文件换成C语言的stdio.h头文件:

原因是cstdio里的内容都被包含在std命名空间中,而stdio.h里的内容暴露在全局里!

C++将C语言的头文件形式全部由.h结尾改成了以c开头,可能是为了和自己的一套规范相匹配,比如标准C++之前iostream的写法是iostream.h。

不仅仅是头文件里定义的各种变量、函数等,我们自己定义的一系列东西如果暴露在全局里,就很容易造成命名冲突,因此我们在工作中使用C++语言进行工作时最好不要展开命名空间,那么接下来我们将继续介绍命名空间的使用以及作用域限定符。

4 命名空间的使用

cpp 复制代码
namespace s3
{
	int a = 10;
	namespace s4
	{
		int a = 20;
	}
    int add(int x, int y)
	{
		return x + y;
	}
}

我拿嵌套命名空间的例子向大家介绍命名空间的使用:

4.1 加命名空间名称及作用域限定符::

cpp 复制代码
#include<iostream>
namespace s3
{
	int a = 10;
	namespace s4
	{
		int a = 20;
	}
    int add(int x, int y)
	{
		return x + y;
	}
}
int main()
{
    std::cout << "s3中的add(1,2)=" << s3::add(1,2) << std::endl;
	std::cout << "s3中的a=" << s3::a << std::endl;
	std::cout << "s4中的a=" << s3::s4::a << std::endl;
	return 0;
}

s4是包含在s3里的,所以要写成s3::s4

如果我们要进行大量的输入输出,一句一句写std::cout岂不是太麻烦了?

4.2 使用using将命名空间中某个成员引入(最推荐)

为什么最推荐?

①减少代码量

②防止同名变量命名冲突

cpp 复制代码
#include<iostream>
using std::cout;
using std::endl;
namespace s3
{
	int a = 10;
	namespace s4
	{
		int a = 20;
	}
}
using s3::a;
using s3::s4;//err
using s3::add;
int main()
{
    cout << "s3中的add(1,2)=" << add(1,2) << endl;//3
	cout << "s3中的a=" << a << endl;//10
	cout << "s4中的a=" << s3::s4::a << endl;//20
	return 0;
}

注意,作用域限定符不支持后面跟命名空间:

4.3 使用using namespace +命名空间名称

温馨提醒:平时我们自己写代码可以用,到公司上班了就最好不要写,和别人冲突了就不好了。

cpp 复制代码
using namespace std;//放在头文件前后都可以
#include<iostream>
//using namespace s3;//放在s3前面就err
namespace s3
{
	int a = 10;
	namespace s4
	{
		int a = 20;
	}
	int add(int x, int y)
	{
		return x + y;
	}
}
using namespace s3;//ok
int main()
{
	cout << "hello world" << endl;
	cout << "s3中的a=" << add(1,2) << endl;
	cout << "s3中的a=" << a << endl;
	cout << "s4中的a=" << s4::a << endl;
	return 0;
}

使用using namespace+命名空间名称,就相当于少写了一层作用域限定符。

需要注意的是,展开自己的命名空间和展开标准命名空间,自己的必须写在命名空间的定义下面,std的既可以写在头文件上方也可以写在头文件下方。

5 总结

本文介绍了C++的命名空间,C++的命名空间是为了解决C语言命名冲突的缺陷提出的,对于命名空间的使用,我推荐大家用4.2中的用法,这样有利于培养起优质的代码习惯!

另外,今天是10/24,祝各位程序员节快乐!

相关推荐
是店小二呀2 分钟前
【C++】C++ STL探索:Priority Queue与仿函数的深入解析
开发语言·c++·后端
ephemerals__10 分钟前
【c++】动态内存管理
开发语言·c++
CVer儿20 分钟前
条件编译代码记录
开发语言·c++
程序猿练习生1 小时前
C++速通LeetCode简单第18题-杨辉三角(全网唯一递归法)
c++·算法·leetcode
汉字萌萌哒1 小时前
【2022 CCF 非专业级别软件能力认证第一轮(CSP-J1)入门级 C++语言试题及解析】
数据结构·c++·算法
th新港1 小时前
CCF201909_1
数据结构·c++·算法·ccf
意如流水任东西1 小时前
[C++]类和对象(上)
开发语言·c++
孤寂大仙v1 小时前
【C++】STL----stack和queue常见用法
开发语言·c++
一丝晨光1 小时前
逻辑运算符
java·c++·python·kotlin·c#·c·逻辑运算符
Code哈哈笑3 小时前
【C++ 学习】多态的基础和原理(10)
java·c++·学习