【C++杂货铺】—— 命名空间 (解决命名冲突等问题)

发布时间:2024年01月23日

目录

🌈前言

📁 命名空间的定义

📁 命名空间的使用

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

●?使用using将命名空间中某个成员引入

●?使用using namespace 命名空间名称 引入

📁 C++输入 和 输出

📁 总结


🌈前言

? ? ? ? 欢迎收看本期【C++杂货铺】,这期内容,我们将围绕C++中内存空间进行讲解。如果你想学习C++,或者刚学完C语言衔接C++,那么这篇文章将会非常有效的帮助你理解。

? ? ? ? 在C语言学习过程中,我们知道同一个作用域下是不能创建同名的变量/函数/结构体的,问题就来了,随着我们不断学起,代码越写越多,让我们起这么多名也不行呀。这时,C++ 的开发者本贾尼·斯特劳斯特卢普就想到了一种方法,就是命名空间,不同命名空间的对象是可以同名的。

📁 命名空间的定义

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

拓:

? ? ? ? C++中域分为 全局域,局部域,命名空间域,类域。目前,如果你还没学习过C++,你只需先了解前三个域即可,类域会在后面的【C++杂货铺讲解】。

? ? ? ? 编译器想要搜索一个变量/函数时,规则如下:

? ? ? ? 1. 首先查找局部域

? ? ? ? 2. 在查找去全局域

? ? ? ? 3. 如果上述操作后,依然没有找到没报错,如果你指定了命名空间,那么编译器会跳过上述步骤,直接进入命名空间进行查找。

? ? ? ? 如何指定一个命名空间呢,就要用到操作符 :: ,即域作用限定符

? ? ? ? 下面,我们来举一个例子,C语言环境下有一个rand函数,是用来生成伪随机数的一个函数,包含在<stdlib.h>这个头文件中,如果我们想用在创建一个变量rand,会发现,编译器会报错。

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
int main()
{
 printf("%d\n", rand);
return 0;
}
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”

? ? ? ? 倘若你使用C++来编写代码,你就可以创建个命名空间将rand变量放入进去。

#include <iostream>
namespace test
{
	int rand;
}
int main()
{
	test::rand = 0;
	return 0;
}

? ? ? ? 以上就是命名空间的应用场景,即避免了同名变量/函数的冲突问题。下面我们来看看命名空间如何创建使用。

📁 命名空间的使用

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

//1. 命名空间中可以定义变量/函数/类型
namespace N1
{
    int a;
    int add(int x,int y)
    {
        return x + y;
    }

    struct Node
    {
        struct Node* next;
        int val;
    }
}

//2. 命名空间可以嵌套
namespace N1
{
    int a;
    int b;
    int Add(int x, int y)
     {
 ? ?     return left + right;
     }
    namespace N2
     {
 ?     ? int c;
 ? ?     int d;
 ? ?     int Sub(int x, int y)
 ? ?     {
 ? ? ? ?     return x - y;
 ? ?     }
     }
}

//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
// test.h
namespace N1
{
    int Mul(int x, int y)
     {
 ? ?     return x * y;
     }
}

? ? ? ? 以上我们就学会了如何创建命名空间,那么如何去使用呢。倘若不加任何东西,是不能直接使用的,正如们上面拓展所讲,编译器会在局部和全局域中搜索,没有指定命名空间会报错。

#include <iostream>

namespace N
{
    int a = 10;
    int b = 20;
}

int main()
{
 // 编译报错:error C2065: “a”: 未声明的标识符
 printf("%d\n", a);
return 0;
}

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

int main()
{
 ? ?printf("%d\n", N::a);
 ? ?return 0; ? ?
}

●?使用using将命名空间中某个成员引入

using N::b;
int main()
{
 ? ?printf("%d\n", N::a);
 ? ?printf("%d\n", b);
 ? ?return 0; ? ?
}

●?使用using namespace 命名空间名称 引入

using namespce N;
int main()
{
 ? ?printf("%d\n", N::a);
 ? ?printf("%d\n", b);
 ? ?Add(10, 20);
 ? ?return 0; ? ?
}

📁 C++输入 和 输出

? ? ? ? 以上,我们就对命名空间有了了解,这也方便你更好的理解下面的内容。我们首先来看看C++中如何输出"Hello World ",当然你也可以是使用纯C写printf函数,也可以使用cout。

#include <iostream>

using namespace std;
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中

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

//using std::cout

//std::cout<<"Hello World" <<endl;

拓:

1. 使用 cout 标准输出对象 ( 控制台 ) cin 标准输入对象 ( 键盘 ) 时,必须 包含 < iostream > 头文件以及按命名空间使用方法使用std
2. cout cin 是全局的流对象, endl 是特殊的 C++ 符号,表示换行输出,他们都包含在包含 <
iostream > 头文件中。
3. << 是流插入运算符, >> 是流提取运算符
4. 使用 C++ 输入输出更方便,不需要像 printf/scanf 输入输出时那样,需要手动控制格式。
C++ 的输入输出可以自动识别变量类型。

? ? ? ? 也就是说cin 和 cout 都是在std这个命名空间里的。如果不是用usingnamespace std的话,可以using每个成员变量,或者+上域作用限定符 :: 。最后的endl就是输出换行的意思,类似与'\n'的功能。

📁 总结

? ? ? ? 总结一下,我们这期内容讲了什么是命名空间,它的作用就是避免命名冲突,如何去定义命名空间,如要注意的是同一个命名空间是不能有同名的变量/函数/结构体对象的,此外,我们还对cin和cout进行了讲解。

stdC++标准库的命名空间,如何展开std使用更合理呢?
1. 在日常练习中,建议直接 using namespace std 即可,这样就很方便。
2. using namespace std 展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型 /
/ 函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模
大,就很容易出现。所以建议在项目开发中使用,像 std::cout 这样使用时指定命名空间 +
using std::cout 展开常用的库对象 / 类型等方式。
最后,如果感觉本期【C++杂货铺】—— 命名空间 (解决命名冲突等问题) 对你有帮助,欢迎点赞,收藏,关注Thanks?(・ω・)ノ
文章来源:https://blog.csdn.net/jupangMZ/article/details/135769258
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。