C++——命名空间(namespace)

这篇具有很好参考价值的文章主要介绍了C++——命名空间(namespace)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. C语言命名冲突

2. 命名空间定义

3. 命名空间使用

  • 可能大家在看别人写的C++代码中,在一开始会包这个头文件:#include<iostream>

这个头文件等价于我们在C语言学习到的#include<stdio.h>,它是用来跟我们的控制台输入和输出的,这里简要提下,后续详谈。

  • 除了上面这个头文件,还有这样一行代码:using namespace std;

namespace就是我们要接触C++的第一个关键字,它就是命名空间。

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

1. C语言命名冲突

 在正式引入namespace前,再来回顾下C语言的命名冲突问题:

#include<stdio.h>
//命名冲突
int rand = 0;
int main()
{
	printf("%d", rand);
	return 0;
}

如上的代码中,头文件我们只用了intclude<stdio.h>,暂无其它。我们定义了全局变量rand,并且代码可以正常编译没有任何错误。

但是要知道C语言存在一个库函数正是rand,但是要包上头文件#include<stdlib.h>,包上了这个头文件,再运行试试:

C++——命名空间(namespace)

这里很明显发生命名冲突了,我们定义的全局变量rand和库里的rand函数冲突

想要解决此问题也非常简单,可能有人会说我修改变量名就可以了,确实可以,但并不是长久之计,如若我在不知情的状态下使用该变量超过100次,难道你要一个一个修改吗,这就充分体现了C语言的命名冲突。

在C++中,引入的命名空间namespace就很好解决了C语言的命名冲突问题。

2. 命名空间定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{ }即可,{}中即为命名空间的成员。

如下:

C++——命名空间(namespace)

 同一个作用域不能出现两个相同变量,此时的rand被关在n1的命名空间域里了,跟其它东西进行了隔离。所以在stdlib.h头文件展开时并不会发生命名冲突。此时rand的打印均是库函数里rand的地址,rand就是一个函数指针,打印的就是地址。

再比如:

C++——命名空间(namespace)

此段代码更充分的体现了加上命名空间,不仅可以避免命名冲突,而且还告诉我们,此时再访问变量m、c、f,均是在全局域里访问的,而xzy这个命名空间域里的变量与全局域建立了一道围墙,互不干扰。不过这里c和m依旧是全局变量,命名空间不影响生命周期

命名空间有三大特性:

  • 1、命名空间可以定义变量,函数,类型
//1. 普通的命名空间
namespace N1 // N1为命名空间的名称
{
	// 命名空间中的内容,既可以定义变量,也可以定义函数,也可以定义类型
	int a; //变量
	int Add(int left, int right) //函数
	{
		return left + right;
	}
    struct ListNode //类型
    {
        int val;
        struct ListNode* next;
    }
 
}
  • 2、命名空间可以嵌套
//2. 命名空间可以嵌套
namespace N2
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace N3
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}
  • 3、同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
namespace N1
{
	int Mul(int left, int right)
	{
		return left * right;
	}
}

3. 命名空间使用

我们都清楚在C语言中,存在局部优先规则,如下:

int a = 0; //全局域
int main()
{
	int a = 1; //局部域
	printf("%d\n", a); // 1 局部优先
	return 0;
}

我们都清楚这里的结果是1,但是如若我非要打印全局域里的a呢?

这里引出域作用限定符 :: ),效果如下:

C++——命名空间(namespace)

加上了( :: ) ,此时访问的a,就是全局域,这里是全局域的原因是“ ::”的前面是空白,如若是空白,那么访问的就是全局域,这么看的话,我在“ ::”前面换成命名空间域,不就可以访问命名空间域里的内容了吗。其实“ ::”就是命名空间使用的一种方式。

 比如我们定义了如下的命名空间:

namespace n1 
{
	int f = 0;
	int rand = 0;
}

现在该如何访问命名空间域里的内容呢?其实有3种方法:

  1. 加命名空间名称及作用域限定符“ ::”;
  2. 使用using namespace 命名空间名称全部展开;
  3. 使用using将命名空间中成员部分展开。
  • 1、加命名空间及作用域限定符“ ::”
int main()
{
	printf("%d\n", n1::f); //0
	printf("%d\n", n1::rand);//0
	return 0;
}

为了防止定义相同的变量或类型,我们可以定义多个命名空间来避免。

namespace ret
{
	struct ListNode
	{
		int val;
		struct ListNode* next;
	};
}
 
namespace tmp
{
	struct ListNode
	{
		int val;
		struct ListNode* next;
	};
	struct QueueNode
	{
		int val;
		struct QueueNode* next;
	};
}

当我们要使用它们时,如下:

int main()
{
	struct ret::ListNode* n1 = NULL;
	struct tmp::ListNode* n2 = NULL;
	return 0;
}

针对命名空间的嵌套,如下:

C++——命名空间(namespace)

 可以这样进行访问:

int main()
{
	struct tx::List::Node* n1; //访问List.h文件中的Node
	struct tx::Queue::Node* n2;//访问Queue.h文件中的Node
}

但是上述访问的方式有点过于麻烦,可不可以省略些重复的呢?比如不写tx::,这里就引出命名空间访问的第二种方法:

  • 2、使用using namespace 命名空间名称全部展开
using namespace tx;

这句话的意思是把tx这个命名空间定义的东西放出来,所以我们就可这样访问:

int main()
{
	struct List::Node* n1; //访问List.h文件中的Node
	struct Queue::Node* n2;//访问Queue.h文件中的Node
}

当然,我还可以再拆一层,如下:

using namespace tx;
using namespace List;
int main()
{
	struct Node* n1; //访问List.h文件中的Node
	struct Queue::Node* n2;//访问Queue.h文件中的Node
}

展开时要注意tx和List的顺序不能颠倒

这种访问方式是可以达到简化效果,但是也会存在一定风险:命名空间全部释放又重新回到命名冲突

C++——命名空间(namespace)

 所以针对某些特定会出现命名冲突问题的,需要单独讨论:

C++——命名空间(namespace)

由此我们得知:全部展开并不好,我们需要按需索取,用什么展开什么,由此引出第三种使用方法。

  • 3、使用using将命名空间中成员展开

针对上述代码,我们只放f出来:

namespace n1
{
	int f = 0;
	int rand = 0;
}
using n1::f;
int main()
{
	f += 2;
	printf("%d\n", f);
	n1::rand += 2;
	printf("%d\n", n1::rand);
}
  • 下面来看下C++的标准库命名空间:
#include<iostream>
using namespace std; //std 是封C++库的命名空间
int main()
{
	cout << "hello world" << endl; // hello world
	return 0;
}

如若省去了这行代码:using namespace std;

想要输出hello world就要这样做:

#include<iostream>
int main()
{
	std::cout << "hello world" << std::endl;
	return 0;
}

当然也可以这样:

#include<iostream>
using std::cout;
int main()
{
	cout << "hello world" << std::endl;
	return 0;
}

这就充分运用到了命名空间。

 文章来源地址https://www.toymoban.com/news/detail-498955.html

到了这里,关于C++——命名空间(namespace)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ 之命名空间namespace【详解】

    命名空间(Namespace)在编程中的作用主要有以下几点意义 避免命名冲突:命名空间提供了一种将标识符(如变量、函数、类等)组织和隔离的方式。不同的命名空间可以拥有相同名称的标识符,避免了不同模块或库之间的命名冲突。 提高可读性和可维护性:通过使用命名空

    2024年02月16日
    浏览(34)
  • 详解C++中的命名空间(namespace)

    个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C++之路】 在C++中,总共有63个,大家还记得在C语言中有多少个吗,没错,在C语言中总共有32个。 下面是C++的: asm do if auto return try contin

    2023年04月19日
    浏览(34)
  • 【C++】命名空间 namespace 与 标准流 iostream ( 命名空间概念简介 | 命名空间定义 | 命名空间使用 | iostream 中的命名空间分析 )

    命名空间 namespace 又称为 名字空间 , 名称空间 , 名域 , 作用域 , 是 C++ 语言 对 C 语言 的扩展 之一 ; C++ 中的 命名空间 namespace 指的是 标识符 的 可见范围 , C++ 标准库中的 所有 标识符 , 都定义在 std 命名空间中 ; 命名空间 英文名称是 \\\" namespace \\\" , name 是 名字 , 名称 的意思 ,

    2024年02月12日
    浏览(41)
  • 【C++技能树】NameSpace --命名空间的使用

      Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接       我会一直往里填充内容哒! 🌈LeetCode专栏:专栏链接       目前在刷初级算法的LeetBook 。若每日一题当中有力所能

    2023年04月16日
    浏览(36)
  • Kubernetes集群命名空间(Namespace)

    Namespace是对一组资源和对象的抽象集合. 常见的 pod, service, deployment 等都是属于某一个namespace的(默认是 default) 不是所有资源都属于namespace,如nodes, persistent volume,namespace 等资源则不属于任何 namespace 使用 kubectl get all --namespace=命名空间名称 可以查看此命名空间下的所有资源

    2024年02月16日
    浏览(33)
  • k8s学习笔记(四):命名空间(namespace)详解

    Kubernetes中的Namespace是一种用于在 集群内部组织和隔离资源 的机制。一个Namespace可以看作是一个 虚拟的集群 ,它将物理集群划分为多个逻辑部分,每个部分都有自己的一组资源(如Pod、Service、ConfigMap等)。 Namespace 适合用于 隔离不同用户创建的资源 用于给集群中的 任何对

    2024年02月12日
    浏览(35)
  • 【C#】【命名空间(namespace)】.NET6.0后支持的顶级语句使用问题

    创建C#项目且使用.Net6.0以上的版本时,默认code会使用顶级语句形式: 1、略去static void Main(String[ ] args)主方法入口; 2、隐式使用(即隐藏且根据代码所需要的类自动调用)其他命名空间(包括): using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Net

    2024年02月08日
    浏览(44)
  • 【C++对于C语言的扩充】C++与C语言的联系,命名空间、C++中的输入输出以及缺省参数

    铁子们好啊!这是阿辉新开的专栏《拿下C++》的第一篇文章,本文主要带大家了解一下C++,带大家从C语言过渡到C++,所以大家首先要有C语言的基础,否则后面的内容你可能会异常懵逼。不会C语言的铁子,这里推荐各位先看阿辉的专栏《爱上C语言》(点击即可跳转,自荐一下

    2024年02月03日
    浏览(35)
  • 计算机语言 之【C++】入门级知识讲解(命名空间,C++输入输出,缺省参数,函数重载,引用,内敛函数,auto关键字,for循环,指针空值nullptr)

    三点睡六点起,阎王夸我好身体 不到三点我不睡,太平间里抢C位 目录: 前言: 本片博客是以学习过C语言之后进入C++学习为前提,讲解C++入门级知识,为C++之后的学习做铺垫 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀

    2024年04月11日
    浏览(129)
  • 【C++】入门 --- 命名空间

    本篇文章是《C++ 初阶》 专栏的第一篇文章,从本专栏开始就进入了C++的学习了哦!本篇的内容是C++入门:命名空间的学习希望烙铁们可以理解消化哦🥰!!! 🚩C++是一种计算机高级程序设计语言,由C语言扩展升级而产生 ,最早于1979年由 本贾尼·斯特劳斯特卢普在ATT贝尔

    2024年02月16日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包