核心简记
- 安全的命名引入方式: using 命名空间名:要引入的名字; 每句只引入一个成员
- string、vector: 标准库类型,见下
- c++对库的实现做了性能要求
- 拷贝构造和赋值有根本的不同,完全俩个操作,在类中可以分别定义。拷贝初始化与直接构造是俩个操作,拷贝初始化和直接初始化区别在是否有=。拷贝初始化只是传一个参,和直接把那个参传到直接构造里效果是一样的。都是构造的罗列之后去选对应的构造,直接构造是自己填实参选择,拷贝初始化是传一个参数。
- string类动态增长是重新分配并拷贝实现的
- 迭代器:定义于容器的的访问器,std实现的类。见下
- 泛型编程:编写的代码可以作用不同的类型、场所。一句通用。c++经常使用!=与==为条件而不是<<=>=>,是因为所有标准库容器都定义了!=与==,但<>就不一定了,类似的还有迭代器与下标访问。
- ->是(*).的简写。.的优先级高于*所以加()
string
位于库:
初始化方式:
这些初始化方式都是类内自定义的,c++可以使类类型像内置类型一样好用。
string对象的操作:
可定义操作:函数、运算符。判断字符可用cctype库
注意size返回的是string::size_type类型,该类型为无符号类型值。为了标准库类型与机器无关。
c++的字面值字串与string类型不同,字面值是const char *
c++兼容了c语言标准库:xxx.h名为cxxx。二者是一样的,不过在cxxx中定义的名字属于std命名空间。为区分模块与方便应该使用cxxx
范围for语句:
用于遍历序列中的每个元素。不是迭代器。范围for内不应该改变其所遍历的序列的大小
问题:
- string的内在字串存储表示?可增长的?在栈中的对象样子?可增长?
- 直接构造与拷贝初始化的不同?string重载了=
string类动态增长是重新分配并拷贝实现的
vector
容器一种,对象的集合。类模板
编译器根据模板创建类或函数称实例化。对象为定义。编译时多态。
vector容纳类型的对象作为元素,引用不是对象所以不存在包含引用的vector。
初始化:
类内初始值初始化只能拷贝初始化或花括号初始化。()是构造对象,{}是列表初始化对象。
vector的操作:
可以用范围for,size_type是每个类定义一个,这里返回的是vector
迭代器
所有标准库容器都可以使用迭代器,类似指针实现的类,用于访问容器元素。
有效的迭代器指向某个元素或尾元素的下一个。
运算符:标准库容器类的迭代都实现了的
迭代器的类型:
都是在各自类下定义的类。类的实现让它与指针一样好用,指的是vector是否const。
const的对象begin与end返回的是const迭代器,其它返回普通。普通想返回const的可以用cbegin()与cend()
使用迭代器时不要改变容器对象大小
迭代器运算:string与vector提供额外的运算符
数组
内置的复合类型,大小不变。数组元素个数也是数组类型的一部分。不能auto,元素为对象,不能是引用。
初始化:
不允许拷贝赋值。
复杂的声明;
左右归约形成的语法树是一样的,这是语法规定的解析方式,()改变了语法树的样子。理解的话是从内到外,从右到左。
可以使用范围for与下标,都是c++语言直接定义的。因为维度是数组的一部分,所以范围for可以
数组在编译时编译器一般会把它转化为指针。数组含大小但是指针不含。注意:指针也是迭代器,可以使用迭代器所有的功能,甚至[]
c风格的字串理解为为const char *类型的,不建议使用,c++用string。可以使用字面值初始化string,
使用数组可以初始化vector:
尽量使用标准库
多维数组是数组的数组
指针不保存数组长度,指针只保存类型,数组类型含长度
a[3]表示的是一个int *的指针,一个int [4]的数组
a表示的是一个int (*)[4]的指针,一个int [3][4]的数组
因为auto会把数组类型当指针,因此慎用auto处理数组
反编译
代码:
x86-64
指令简记
movsx是带符号扩展的转移,也就是说不够的位数用符号补齐
SSE有8个128位独立寄存器(XMM0~XMM7).
分析
|
|
语句块里的变量也直接定义在函数的栈里了,这部分的访问控制由编译器检查。布尔表达式确实如规定所实现。
注意在函数栈中构造的对象在函数结束时编译器自动添加析构函数调用。此外释放顺序与定义顺序相反。为的是防止使用空指针,依赖者先释放,不影响被依赖者。
对象的构造不论哪种方式都是传入this与参数,实现构造。
对象的操作大多都被定义为函数。传入this。
范围for相当于c式:
范围for调用的函数就是迭代器的函数,也就是说范围for可翻译为:
不过范围for里的end是提前取出之后判断的。普通for是判断时取end。
普通for:
ARM64
指令简记
UXTB 无符号(Unsigned)扩展一个字节(Byte)到 32位
分析
|
|
这里看下:
汇编的表示只有值,传入的变量实质是传入变量的值。这里数组的地址是var_14C但a的地址是var_288也就是说a是一个指针,指针存有var_14C。当调用mencpy函数时,传入的是var_14C,也就是对象的值。
一定明确:汇编下只有地址:值。 寄存器:值 一切语法的表示最后都是这个样子。过程间传递的都是值。而且都是拷贝到指定寄存器传递的。指针就是一个值是地址的对象。