💓博主CSDN主页:杭电码农-NEO💓
⏩专栏分类:C++初阶之路⏪
🚚代码仓库:NEO的学习日记🚚
🌹关注我🫵带你学习排序知识
🔝🔝
命名空间
- 1. 前言
- 2. C++发展历史
- 3. C++现状
- 4. C语言命名冲突
- 5. 命名空间
- 6. 命名空间的使用
- 6.1 方法一
- 6.2 方法二
- 6.3 方法三
- 7. 对命名空间展开的思考
- 8. 总结以及拓展
1. 前言
对于复杂的问题,规模较大的程序
需要高度的抽象和建模时
C语言不再适合应用于这种场景
于是在1982年
C++创始人 Bjarne Stroustrup
在C语言基础上引入面向对象编程概念
本节内容将在介绍完C++个方面的内容后
讲解C++入门第一课:命名空间的内容
2. C++发展历史
1979年,贝尔实验室的本贾尼等人试图分析unix内核的时候,试图将内核模块化,于是在C
语言的基础上进行扩展,增加了类的机制,完成了一个可以运行的预处理程序,称之为C with
classes。
阶段 | 内容 |
---|---|
C with classes | 类及派生类、公有和私有成员、类的构造和析构、友元、内联函数、赋值运算符 |
C++1.0 | 添加虚函数概念,函数和运算符重载,引用、常量等 |
C++2.0 | 更加完善支持面向对象,新增保护成员、多重继承、对象的初始化等等 |
C++3.0 | 进一步完善引入模板,解决多重继承产生的二义性问题和相应构造和析构的处理 |
C++98 | C++标准第一个版本,以模板方式重写C++标准库,引入了STL(标准模板库) |
C++03 | C++标准第二个版本,语言特性无大改变,主要:修订错误、减少多异性 |
C++05 | C++标准委员会发布了一份计数报告,正式更名C++0x |
C++11 | 增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等 |
C++14 | 对C++11的扩展,主要是修复C++11中漏洞以及改进,比如:泛型的lambda表达式,auto的返回值类型推导,二进制字面常量等 |
C++17 | 在C++11上做了一些小幅改进,增加了19个新特性,比如:static_assert()的文本信息可选,Fold表达式用于可变的模板,if和switch语句中的初始化器等 |
C++20 | 自C++11以来最大的发行版,引入了许多新的特性,比如:模块(Modules)、协程(Coroutines)、范围(Ranges)、概念(Constraints)等重大特性,还有对已有特性的更新:比如Lambda支持模板、范围for支持初始化等 |
C++23 | 正在制定中 |
3. C++现状
C/C++在TIOBE编程语言社区
常年位居前五
在23年更是霸榜前三!
关于C++23和最新的C++26
最前沿的改动文章给大家分享两篇
C++23前沿
C++26前沿
实际生活中
C++运用的地方非常多
比较典型的有:
- 操作系统以及大型系统软件开发
- 服务器端开发
- 游戏开发
- 嵌入式和物联网领域
- 数字图像处理
- 人工智能的算法核心领域
在校招笔试面试中
C++更是重量级的存在
4. C语言命名冲突
我们在写C语言时,会遇见这种问题:
取变量名时可能会和库中得变量名冲突
#include<stdio.h>
#include<stdlib.h>
int rand = 10;
int main()
{
printf("%d", rand);
return 0;
}
此时运行程序会报错:
这是因为在库中有了rand这个函数,再次使用rand这个名字定义变量或者函数时,编译器会分不清你到底想使用哪个rand
5. 命名空间
C++为了解决C语言上述的问题
引出了命名空间这种玩法
(C++兼容C语言的所有语法)
定义命名空间,需要使用到namespace关键字
后面跟命名空间的名字,然后接一对{}
{}中即为命名空间的成员
比如:
namespace NEO
{
// 命名空间中可以定义变量/函数/结构体
int rand = 10;
int Add(int left, int right)//函数
{
return left + right;
}
struct Test//结构体
{
int a[10];
int val;
};
}
命名空间相当于一个独立的作用域
命名空间中所有内容都局限于该命名空间中
(注:命名空间可以嵌套定义)
拓展:
一个项目或者源文件可以有多个命名空间
它们的名字可以相同
相同名字的空间将会合并为一个空间
6. 命名空间的使用
6.1 方法一
方法一:不展开命名空间时
使用 :: 操作符
namespace NEO
{
// 命名空间中可以定义变量/函数/结构体
int rand = 10;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
int main()
{
int a = NEO::rand;
int x = NEO::Add(10,20);
printf("%d", NEO::rand);
return 0;
}
在命名空间NEO里面
你如果想使用一个变量或者函数
应该在这之前加上:
空间名 ::
6.2 方法二
方法二:展开命名空间
在空间NEO后面加上
using namespace NEO;
这句话的意思是:
将空间NEO展开为全局域
我们在看C++程序时经常看见:
using namespace std;
std就是C++的标准库
已知C++的输出函数是cout
cout是在标准库中定义的
假设标准库没有展开
我们使用cout时,编译器在全局域
没有找到cout就会报错.
这时就应该这样写:
std::cout << "hello world" << ;
当NEO空间被展开后
空间里的所有内容可以直接使用:
#include<stdio.h>
namespace NEO
{
// 命名空间中可以定义变量/函数/结构体
int rand = 10;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
using namespace NEO;
int main()
{
int a = rand;
printf("%d", rand);
return 0;
}
6.3 方法三
方法三:展开空间中部分内容
假设NEO空间中的rand使用频率很高
可以将rand变量单独展开到全局域
using NEO::rand;
若Add函数使用频率很高:
using NEO::Add;
using NEO::rand;
int main()
{
int a = rand;//rand展开了直接用
int x = NEO::Add(10,20);//Add函数没有展开,要使用 ::
printf("%d", rand);
return 0;
}
7. 对命名空间展开的思考
假设我们将自定义NEO空间和
标准库的std空间同时展开
那么整型变量rand和rand函数
同时暴露在全局域
我们再去使用它时也会报错
using namespace std;
using namespace NEO;
所以直接展开std标准库也有冲突风险
但是不展开的话,写输入输出会很麻烦
那么平时写代码时应该怎么办?
结论:
写项目时,尽量不要展开标准库
日常练习时应该展开标准库
写项目使用部分常用内容展开
8. 总结以及拓展
命名空间的存在奠基了C++
能作为创建一个大工程的语言
大工程往往会分组安排任务
每个小组可以使用不同的命名空间
每个空间定义相同的名字也没事
这对于开发者来说十分方便!
拓展:
分享几个用C++开发的知名游戏:
- 绝地求生
- 巫师三
- 黑暗之魂
- 无主之地2
- 生化危机5