目录
1.Cpp的基本信息(作为了解)
1.1Cpp的历史
1.2Cpp的版本迭代与更新
1.3Cpp在工作中领域的应用
2.Cpp的第一个代码(helloworld)
3.命名空间(重要)
3.1namespace的定义
3.2namespace的价值
3.3命名空间的使用
1.Cpp的基本信息(作为了解)
1.1Cpp的历史
C++的起源可以追溯到1979年,当时BjarneStroustrup(本贾尼·斯特劳斯特卢普,这个翻译的名字不 同的地⽅可能有差异)在⻉尔实验室从事计算机科学和软件⼯程的研究⼯作。⾯对项⽬中复杂的软件开 发任务,特别是模拟和操作系统的开发⼯作,他感受到了现有语⾔(如C语⾔)在表达能⼒、可维护性 和可扩展性⽅⾯的不⾜。 1983年,BjarneStroustrup在C语⾔的基础上添加了⾯向对象编程的特性,设计出了C++语⾔的雏形, 此时的C++已经有了类、封装、继承等核⼼概念,为后来的⾯向对象编程奠定了基础。这⼀年该语⾔被 正式命名为C++。 在随后的⼏年中,C++在学术界和⼯业界的应⽤逐渐增多。⼀些⼤学和研究所开始将C++作为教学和研 究的⾸选语⾔,⽽⼀些公司也开始在产品开发中尝试使⽤C++。这⼀时期,C++的标准库和模板等特性 也得到了进⼀步的完善和发展。 C++的标准化⼯作于1989年开始,并成⽴了⼀个ANSI和ISO(InternationalStandards Organization)国际标准化组织的联合标准化委员会。1994年标准化委员会提出了第⼀个标准化草 案。在该草案中,委员会在保持斯特劳斯特卢普最初定义的所有特征的同时,还增加了部分新特征。 在完成C++标准化的第⼀个草案后不久,STL(StandardTemplateLibrary)是惠普实验室开发的⼀系 列软件的统称。它是由AlexanderStepanov、MengLee和DavidRMusser在惠普实验室⼯作时所开发 出来的。在通过了标准化第⼀个草案之后,联合标准化委员会投票并通过了将STL包含到C++标准中的 提议。STL对C++的扩展超出C++的最初定义范围。虽然在标准中增加STL是个很重要的决定,但也因 此延缓了C++标准化的进程。 1997年11⽉14⽇,联合标准化委员会通过了该标准的最终草案。1998年,C++的ANSI/IS0标准被投⼊ 使⽤。
1.2Cpp的版本迭代与更新
目前主流使用的 C++ 版本主要是 C++11、C++14 和 C++17,不同的应用场景和开发团队会根据实际需求进行选择。
1.3Cpp在工作中领域的应用
C++ 凭借其高性能、高灵活性和广泛的硬件访问能力,在众多工作领域都有重要应用。服务器端、游戏(引擎)、机器学习引擎、⾳视频处理、嵌⼊式软件、电信设备、⾦融 应⽤、基础库、操作系统、编译器、基础架构、基础⼯具、硬件交互等很多⽅⾯都有。涉猎方面很广我取几个例子小小展开说明。
1. ⼤型系统软件开发。如编译器、数据库、操作系统、浏览器等等。
2. ⾳视频处理。常⻅的⾳视频开源库和⽅案有FFmpeg、WebRTC、Mediasoup、ijkplayer,⾳视频 开发最主要的技术栈就是C++。
3. 嵌⼊式开发。嵌⼊式把具有计算能⼒的主控板嵌⼊到机器装置或者电⼦装置的内部,通过软件能够 控制这些装置。⽐如:智能⼿环、摄像头、扫地机器⼈、智能⾳响、⻔禁系统、⻋载系统等等,粗 略⼀点,嵌⼊式开发主要分为嵌⼊式应⽤和嵌⼊式驱动开发。
4. 游戏引擎开发。很多游戏引擎就都是使⽤C++开发的,游戏开发要掌握C++基础和数据结构,学习 图形学知识,掌握游戏引擎和框架,了解引擎实现,引擎源代码可以学习UE4、Cocos2d-x等开源 引擎实现。
2.Cpp的第一个代码(helloworld)
由于C++是向下兼容C语言的所以C语言的代码只要包含对应头文件是可以在C++环境下运行的。
- #include<stdio.h>
- int main()
- {
- printf("hello world\n");
- return 0;
- }
复制代码
当然我们既然要学Cpp那么就要用Cpp的语法来实现hello world。
- #include <iostream>//Cpp头文件
- using namespace std;//调用标准命名空间
- //主函数
- int main()
- {
- cout<<"hello world"<<endl;
- return 0;
- }
复制代码
解释头文件iostream,我们不妨把它拆开成io + stream来看可以理解位input output以及stream(流),即可以将该头文件理解成输入输出流的头文件。
这段代码往下走我们就可以发现出现了 using namespace std;
从字面意思来看就是使用命名空间标准的;命名空间至一概念后面面会讲到。在这里为了好理解代码大家可以简单的理解为Cpp提供的一个标准命名变量。
接下来是cout和endl稍后的章节会说到。
3.命名空间(重要)
在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全 局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名 冲突或名字污染,namespace关键字的出现就是针对这种问题的。
3.1namespace的定义
定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。
namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下 ⾯的rand不在冲突了。
C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。
局部域和全局域除了会影响 编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。
namespace只能定义在全局,当然他还可以嵌套定义。
项⽬⼯程中多⽂件中定义的同名namespace会认为是⼀个namespace,不会冲突。
C++标准库都放在⼀个叫std(standard)的命名空间中。
思考一下,既然命名空间也就是命名域内可以声明定义变量,那它和全局变量有什么区别呢?
首先,他不能像全局变量那样随时随地的调用需要通过' :: ',在引用上面所说过的话“局部域和全局域除了会影响 编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。“比如以下代码。
- #include <iostream>
- namespace MyNamespace {
- void func() {
- // 命名空间内函数的局部变量
- int localVar = 30;
- std::cout << "局部变量的值: " << localVar << std::endl;
- }
- }
- int main() {
- MyNamespace::func();
- // 此时 localVar 已销毁,无法访问
- return 0;
- }
复制代码
所以命名空间域并不会影响变量的生命周期,该变量的生命周期只会像在跟函数栈帧一起创建和销毁,它的生命周期与命名空间没有关系。
3.2namespace的价值
c语⾔项⽬类似下⾯程序这样的命名冲突是普遍存在的问题,C++引⼊namespace就是为了更好的解决 这样的问题
- #include <stdio.h>
- #include <stdlib.h>
- int rand = 10;
- int main()
- {
- // 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
- printf("%d\n", rand);
- return 0;
- }
复制代码
3.3命名空间的使用
编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。所以 下⾯程序会编译报错。所以我们要使⽤命名空间中定义的变量/函数,有三种⽅式:
1.指定命名空间访问,项⽬中推荐这种⽅式。
比如现在有个命名空间叫Mynamespace如果我现在要访问里面的变量那么我就可以通过
Mynamespace::a()之就相当于访问这个命名空间内的函数。
2.using将命名空间中某个成员展开,项⽬中经常访问的不存在冲突的成员推荐这种⽅式。
这种方式在命名空间前加上using (命名空间名)相当于展开该namespace中的所有函数与变量。这回导致该变量、函数与全局变量没有太大差别,这样会加大声明冲突的问题。注意:using 指令在全局作用域,那么在整个程序中都可以直接使用这些展开的变量和函数;如果在局部作用域,那么只在该局部作用域内可以直接使用。
3.展开命名空间中全部成员,项⽬不推荐,冲突⻛险很⼤,⽇常⼩练习程序为了⽅便推荐使⽤。
与2的情况类似。