施磊C++初级笔记
1 深入学习C++语言先要练好的内功
1.1 掌握进程虚拟地址空间区域划分
1.2 从指令角度掌握函数调用堆栈详细过程
具体得看视频,讲述了main函数调用sum方法每步的空间变化。
1.3 从编译器角度理解C++代码的编译和链接原理
2 C++基础
2.1 深入理解new,delete
malloc和free称作C的库函数,new和delete称作运算符;
new不仅可以做内存开辟,还可以做内存初始化操作;
malloc开辟内存失败,是通过返回值和nullptr作比较;而new开辟内存失败,是通过抛出bad_alloc类型的异常来判断;
1 | // new有多少种? |
2.2 C++的const
const怎么理解?
const修饰的变量不能再作为左值!!!初始化完成后值不能被修改!!!
C和C++中的区别是什么?
C中const修饰的量不叫常量,叫常变量 ;
C++中const必须初始化,叫常量;
C++中若
1 | int b = 20; |
此时a已经被修改了,就是常变量而不是常量了,因为其初始值不是一个立即数。
const编译方式不同,C中const当作一个变量来编译生成指令的;C++中,所有出现const常量名字的地方都会被常量的初始值替换;
2.3 const和一二(多)级指针的结合应用
const修饰的量常出现的错误
1.常量不能再作为左值;(直接修改)
2.不能把常量的地址泄露给一个普通的指针或者普通的引用变量;(如下做了间接修改)
1 | const int a = 10; |
const和一级指针的结合
1 | const int *p; // p指针可以指向任意int类型的内存,但无法通过指针间接修改指向的内存的值(离const最近的类型为int) |
C++的语言规范:const修饰的使离它最近的类型
const和一级指针的结合有两种情况:
一种是使指针是常量,无法再指向其他内存;一种是使指针指向的内存的值是常量,无法在被修改。
总结,const和指针的类型转换公式:
int <= const int 是错误的!**
const int <= int 是可以的!**
int** <= const int**是错误的!
const int** <= int**是错误的!
const如果右边没有指针*的话,const是不参与类型的。
const和二级指针的结合
1 | const int **q; // **q不能被赋值 |
2.4 C++的引用
引用和指针的区别?
引用是一种更安全的指针。
1.引用是必须初始化的,指针可以不初始化;
2.引用只有一级引用,不存在多级引用;指针可以有一级指针,也可以有多级指针;
3.定义一个引用变量和定义一个指针变量其汇编指令是一模一样的;通过引用变量修改所引用内存的值,和通过指针解引用修改指针指向内存的值,其底层指令也是一模一样的;
右值引用
1.int &&c = 20; 专门用来引用右值类型,指令上,可以自动产生临时量,然后直接引用临时量 c = 40;
2.右值引用变量本身是一个左值,只能用左值引用来引用它;
3.不能用一个右值引用变量来引用一个左值;
1 | int array[5] = {}; |
1 | int a = 10; // 左值,它有内存,有名字,值可以修改 |
const、一级指针、引用的结合
1 | // 写一句代码,在内存0x0018ff44处写一个4字节的10 |
2.5 函数重载
什么是函数重载
1.一组函数,其中函数名相同,参数列表的个数或者类型不同,那么这一组函数就称作函数重载;
2.一组函数要称得上重载,一定先是处在同一个作用域当中的;
3.const或者volatile,是怎么影响形参类型的;
4.一组函数,函数名相同,参数列表也相同,仅仅是返回值不同不叫重载;
请解释一下多态?
静态(编译时期)的多态:函数重载
动态(运行时期)的多态:
C++为什么支持函数重载,C语言不支持函数重载?
C++代码产生函数符号的时候,函数名+参数列表类型组成的!
C代码产生函数符号,函数名来决定!
2.6 inline函数
inline内联函数和普通函数的区别
inline函数:在编译过程中,就没有函数的调用开销了,在函数的调用点直接把函数的代码进行展开处理了
inline函数不再生成相应的函数符号
inline只是建议编译器把这个函数处理成内联函数,但是不是所有的inline都会被编译器处理成内联函数——递归
debug版本上,inline是不起作用的;inline只有在release版本下才能出现
g++ -c main.cpp -02 objdump -t main.o
3 C++面向对象
3.1 this指针
this指针 => 类 => 很多对象 共享一套成员方法
成员方法,方法的参数都会添加一个this指针
构造函数:定义对象时,自动调用的;可以重载的;构造完成,对象产生了
析构函数:不带参数,不能重载,只有一个析构函数;析构完成,对象就不存在了
OOP语言的四大特征是?
抽象 封装/隐藏 继承 多态
3.2 对象的深拷贝和浅拷贝
对象默认的拷贝构造是做内存的数据拷贝
关键是对象如果占用外部资源,那么浅拷贝就出现问题了!(占用同一个资源析构两次就会出错!)
此时(对象的浅拷贝出现问题了)就需要自定义拷贝构造函数和赋值函数(运算符重载)
3.3 构造函数的初始化列表
初始化列表做初始化和在函数体内初始化区别?
int amount = 0;和 int amount; amount = 0;的区别,若数据类型为自定义类型,未指定该自定义类型的构造函数(调用默认构造函数),则无法成功构造。