从本节开始,我开始学习 《重学C++ 重构你的C++知识体系》 这门课,这是一门慕课的课程,帮助我系统学习C++。

知识大纲

一、C++基本语法

- 数据类型与声明
- 标识符和关键字
- 常量与变量
- 算术运算符、关系运算符、逻辑运算符
- 初等表达式、Lambda表达式


二、C++基本词法
- 最基本容器-数组
- const指针
- 函数指针
- 各类指针分析
- 避免野指针
- 防止内存泄露
- 智能指针使用
- C++内存分配方式
- 字符串
- Redis项目字符串处理

三、C++基本句法
- 赋值、判断与循环
- 函数基础
- 内联函数
- 递归函数本质
- 枚举类型
- 结构体:包容一切
- 联合体:高效组合
- 类与面向对象
- 命名空间

四、C++高级语法
- 类型转换
- 强制类型转换
- 异常exception
- IO,最难设计的模板
- 文件操作
- 多线程 C++新标准的运用
- 模板编程应用

五、C++编程思想进阶
- 再议Class
- 运算符重载
- 深拷贝与浅拷贝
- 面向对象的思想,误区
- 常见面向对象设计模式
- 模板编程,C++精髓

六、C++高效编程进阶
- STL常见容器:顺序容器、关联容器
- 算法Algorithm
- 函数对象 Function Objects
- 迭代器iterators
- 生成器Allocators
- C++的内存分配问题
- STL的整体架构和思想
- 更安全的字符串:STL string
- CStreams、cin、
- C++的瑞士军刀:boost库
- C++最新标准/陷阱和经验
- C++中常见的编程范式    

导语

  1. 使用不同的语言可能是人类社会进步的一大阻碍。

  2. 不同的语言会产生不同的思想,语言体现了思考的本质。

我非常赞同这句话!!

  1. C++主要用来做什么
  • 大型桌面应用程序(如Google Chrome 和 Microsoft Office)
  • 大型网站的后台,如Google的搜索引擎
  • 游戏和游戏引擎(如Unity)
  • 视觉库和AI引擎(如OpenCV和TensorFlow)
  • 数据库(Microsoft SQL Server 和 Mongodb)
  • 其它(自动驾驶领域、嵌入式设备)

C++开发成本比较高,对于内存和CPU要求很高的场景或者低功耗的场景,目前来说C++是最合适的语言。

一、C++基础语法

(一)数据类型的内部结构

C++中每个变量都有其数据类型,数据类型决定这变量所占内存空间的大小和部分方式、该空间能存储值的范围,以及变量能参与的运算。

(二)定义常量方法

  1. 使用#define,如: #define PI 3.14;
  2. 使用const,如:const double PI = 3.14;

注明:尽量使用const定义变量,#define 不会在编译器报错.

章节延伸题思考

问题1:请教一个C++问题,我声明了一个对象HelloObject,在这个对象里我定义了10个int64的整数,当我声明HelloObject的时候,这个对象的内存分布是怎样的?

答案:
在C++中,对象的内存布局是由对象的成员变量和对齐规则决定的。对于一个包含10个int64整数的HelloObject对象,其内存布局可能如下所示:

1
2
| int64_1 | int64_2 | int64_3 | int64_4 | int64_5 |
| int64_6 | int64_7 | int64_8 | int64_9 | int64_10|

每个int64整数占据8个字节的内存空间,按照声明的顺序依次排列在对象的内存中。由于int64的对齐要求通常是8字节,因此每个int64整数会被对齐到8字节的边界上。

需要注意的是,内存布局可能受到编译器的优化和对齐规则的影响。编译器可能会对对象的内存布局进行优化,例如进行字段重排或填充字节,以提高内存访问的效率。因此,实际的内存布局可能与上述示例有所不同。如果需要确切地了解对象的内存布局,可以使用sizeof运算符来获取对象的大小,并使用offsetof宏来获取对象成员的偏移量。

问题2:这些内存空间是在堆上开辟的吗? 还是在栈上开辟的?

答案:
在C++中,对象的内存空间可以在堆上或栈上分配,具体取决于对象的声明方式。

如果你在函数内部声明了一个局部的HelloObject对象,例如:

1
2
3
4
void foo() {
HelloObject obj;
// ...
}

那么这个对象会在函数的栈帧中分配内存,也就是在栈上开辟空间。当函数执行完毕时,栈帧会被销毁,对象的内存也会自动释放。

如果你使用new运算符在堆上动态分配HelloObject对象,例如:

1
HelloObject* obj = new HelloObject();

那么这个对象会在堆上分配内存,需要手动使用delete运算符来释放内存,以防止内存泄漏:

1
delete obj;

需要注意的是,堆上分配的对象的生命周期不会受限于作用域,除非手动释放内存,否则对象会一直存在,直到显式地调用delete来释放内存。

二、彻底学完C++指针

(一)指针的基本含义

指针本身就是一个变量,也就是指针变量,它的值就是另外一个变量的地址。

通过一个指针访问它所指向地址的过程称为 间接访问(indirection)或者 引用指针(dereferencing the point)

(二)RAII

RAII 是 C++ 所特有的资源管理方式,现在主流的编程语言中,C++是唯一一个依赖RAII来做资源管理的。

RAII 依托栈和析构函数来对资源进行管理。

RAII 有些比较成熟的智能指针代表: std::auto_ptr 和 boost:shared_ptr

(三)智能指针 auto_ptr

规避空指针、野指针带来的问题:

  1. 使用更安全的指针:智能指针
  2. 不使用指针,使用更安全的方式:引用&

1. auto_ptr(已废弃)

使用 auto_ptr 会发生所有权转移,当有新的 auto_ptr 访问对象后,原来的指针就不再拥有这个对象了,原对象会被重置为 nullptr。

2. unique_ptr

专属指针,unique_ptr 禁止了拷贝语义,默认禁止了所有权转移。
如果想转移所有权可以使用 std::move()。

3. shared_ptr

当引用技术为0时,该对象没有被使用,可以进行析构。

4. 引用

引用是一种人特殊的指针吗,是不允许被修改的指针。