calloc=malloc+memset
new(08)
功能保持一致,用法简化
可以支持初始化
()是初始化,[]是多个空间
自定义对象初始化
new对象可以调用默认构造,多个对象多次调用构造函数和析构函数
隐式对象初始化,匿名对象初始化
1,2的中间会生成一个匿名对象去转换
c++写链表
new申请的空间不用再判空(他会抛出异常)
如果new换成malloc就不会调用构造函数初始化,push就会 出错,free的话没有调用析构函数
new的作用在这分为两步,1开空间(栈对象的空间),2调用构造函数
operator new和operator delete函数
在这不会内存泄漏,因为p1是内置类型,operator new 【】会调用operator new,再调用malloc再调用构造函数,但是内置类型不调用构造,delete也不用调用析构,所以这三个都不会出现问题
下面报错是因为指针位置不对
new开辟40个字节,其实是44个字节, delete【】会识别前面的字节知道有多个, 他就会取10个字节调用析构函数,但是free和delete不会识别
右边没出错是因为A里面没有自定义析构,其实也要多开4个字节调用析构函数但是编译器默认生成的析构什么都没做(不掉也罢)
这样就不会报错了(前面识别的字节剪掉了,但是析构次数没有调用够)
总结:一定要匹配使用
placement-new定位new
显示调用构造函数
相当于new和delete功能,很少用,从内存池申请的内存池才需要自己调用
malloc/free和new/delete区别
模版
template
template<typename T>或<class T>或多参数<typename T1,typename T2>
如果要两个栈,一个存int,一个存double就不能用typedef了 (实际上是两个类)
注意,当类型不一样时候
要么改变类型,要么整体类型改变 (以给的参数为主)
如果有两个函数(其中一个是模版)会优先调用模版,除非像下面一样显示调用
有时候必须显示调用(不然T不知道类型)
vector(顺序表)必须显示调用
模版的声明和定义分离()跟常规函数不一样,模版的类名是Vector,类型是Vector<T>
STL
容器就是数据结构,空间配置器就是内存池
string
其实是模版
支持带参数,支持流插入,流提取
字符拼接
两种写法相同,第一个调用构造,第二个是构造+拷贝构造+优化,单参数的构造函数支持优化
迭代器iterator
迭代器都是指定在内域里面的(而且屏蔽了底层)
遍历数据结构的一种方式(一种指针)(_str,_size,_capacity)
可读(<也可以,但是不要用,因为他是通用的(当内存不连续的时候(如list顺序表)就不可以用))
可读 可写
rbegin,rend,他的++不是倒着走,还是正着走
auto
范围for
自动取容器或者数组里面的字符依次给ch(范围for跟迭代器底层相似)
原理:编译时编译器替换迭代器
这里是*it赋值给ch
不能用ch++修改,必须要引用才能修改,引用后ch就是*it(it是hello worlo的指针*it就是h)的别名
这里func(S1)传参为了避免拷贝,和深拷贝,用引用,加上const防止更改,但是会报错,因为迭代器iterator是读 写都支持的,但是这里const修饰后就不能写了,所以c++11里面iterators里面有了cbegin和cend(crbegin和crend) c是const的意思(c++11后加的)
所以有两个版本因为下面s是const对象要调用const的begin,const版本的begin要返回const版本的迭代器
这时候用auto贼香
正向迭代器,返向迭代器,和给const访问和非const迭代器
从pos开始到len长度的为止
npos是缺省参数-1的补码是全1,全1无符号就是整形的最大值12亿9千万(4G)
s1.size()-6就是从6带=到最后
从开始的 前n个区初始化
区间初始化(比如说第一个和最后一个不要了)
string还可以赋值
capacity
size不算/0 ,最早是length,后来是size,size更通用更合适
clear
clear不会清理空间的(还有析构函数呢)
empty是判空
max_size是最大能开多长空间
reserve
resize
/0为什么要有,因为还要兼顾c语言,说不定什么时候就要调用c接口