该课程也可以叫C++ 标准库——体系结构与内核分析;课程精髓是从源代码分析C++STL之体系结构,而STL正是泛型编程最成功的作品,所以也是以STL为标准深层次的探讨泛型编程。
![](https://img.haomeiwen.com/i3138918/9d0a85452f898b3e.png)
迭代器像是泛化的指针;
迭代器串联起算法和容器;
adapter可以转换容器、迭代器和仿函数
![](https://img.haomeiwen.com/i3138918/75037b8e58f8f4dc.png)
![](https://img.haomeiwen.com/i3138918/52b84a2ba027d3ed.png)
![](https://img.haomeiwen.com/i3138918/3e701badc13d8f11.png)
![](https://img.haomeiwen.com/i3138918/b34fb08a6e05282d.png)
头部为第一个元素,尾部是最后一个元素位置的下一个位置
![](https://img.haomeiwen.com/i3138918/1b1dc2fc86b9096f.png)
![](https://img.haomeiwen.com/i3138918/746c0b939ea1cd26.png)
![](https://img.haomeiwen.com/i3138918/aba601b54a58ece0.png)
![](https://img.haomeiwen.com/i3138918/6d238af82d2ba4ce.png)
序列式容器
![](https://img.haomeiwen.com/i3138918/45a4ae488c17068e.png)
和c语言的数组一样,大小固定,之后不能改,size大小是常量才可以
![](https://img.haomeiwen.com/i3138918/e8a844092aa6c29d.png)
两倍增长 扩充,会有很多内存碎片
![](https://img.haomeiwen.com/i3138918/e9471d4136ec5931.png)
![](https://img.haomeiwen.com/i3138918/bb9b10ccf8df3b0e.png)
优先使用容器自带的迭代器,原因是:标准库的sort中需要使用到随机访问迭代器,而list这类数据结构无法提供随机访问能力,所以内置一个sort不使用随机访问迭代器进行排序
![](https://img.haomeiwen.com/i3138918/c1ce3d19d4bcc070.png)
![](https://img.haomeiwen.com/i3138918/a36eb6716e0d2f9f.png)
所属gnu c++ 非标准c++库 单向链表
![](https://img.haomeiwen.com/i3138918/bc442cf5b68d200f.png)
可以向前或向后生长,分段连续
每次扩充一个buffer,buffer多大看后续?
![](https://img.haomeiwen.com/i3138918/eae6e737be01de37.png)
![](https://img.haomeiwen.com/i3138918/cff97d690d526cfd.png)
![](https://img.haomeiwen.com/i3138918/8469bcd6c9a1642a.png)
关联式容器
![](https://img.haomeiwen.com/i3138918/aba6ea4c7521ec23.png)
底层数据结构是红黑树
![](https://img.haomeiwen.com/i3138918/17222f33746d71ca.png)
底层数据结构是红黑树
![](https://img.haomeiwen.com/i3138918/86f891e29f5bac25.png)
![](https://img.haomeiwen.com/i3138918/90ebfc42f139f3f9.png)
![](https://img.haomeiwen.com/i3138918/edab49d4cf0e62e3.png)
![](https://img.haomeiwen.com/i3138918/b6519b9fa0bf5271.png)
![](https://img.haomeiwen.com/i3138918/ab0e6da777086c82.png)
![](https://img.haomeiwen.com/i3138918/fd7608d98dbd861f.png)
hashtable做支撑,bucket后面是一个链表(可以是单向也可以是双向),bucket一定比元素数多,如果bucket的数量与元素数量相等,那么就会扩充bucket的数量为两倍,然后重新hash
![](https://img.haomeiwen.com/i3138918/732037c23b352776.png)
![](https://img.haomeiwen.com/i3138918/255704606a38b6e9.png)
分配器
![](https://img.haomeiwen.com/i3138918/03c174de7765ccd1.png)
![](https://img.haomeiwen.com/i3138918/d4be283ebd19d2fc.png)
![](https://img.haomeiwen.com/i3138918/3059876c932f3e2f.png)
1代表一个元素,直接使用分配器的时候,需要自己申请和释放,不建议直接使用 分配器
![](https://img.haomeiwen.com/i3138918/eb925ea299bdaf3e.png)
![](https://img.haomeiwen.com/i3138918/4044abb75d3c3ebd.png)
![](https://img.haomeiwen.com/i3138918/15f7fa883a587810.png)
![](https://img.haomeiwen.com/i3138918/19e562865c24a615.png)
![](https://img.haomeiwen.com/i3138918/3d7e76865be495ab.png)
![](https://img.haomeiwen.com/i3138918/ebe78b87ed0bc9b6.png)
运算符重载的标准是模拟整数的操作
![](https://img.haomeiwen.com/i3138918/eae523fc031ba429.png)
![](https://img.haomeiwen.com/i3138918/50fdf075feca80f8.png)
![](https://img.haomeiwen.com/i3138918/f8742704e0bd0e55.png)
![](https://img.haomeiwen.com/i3138918/a49df5d73f686683.png)
![](https://img.haomeiwen.com/i3138918/e75ffe8e9c27d0af.png)
![](https://img.haomeiwen.com/i3138918/fe49b868781b9738.png)
![](https://img.haomeiwen.com/i3138918/a30dd002218fada6.png)
![](https://img.haomeiwen.com/i3138918/b2b2dfcc234ba062.png)
![](https://img.haomeiwen.com/i3138918/01a49d44cb26cb36.png)
类模板可以 局部特化,分为两种数量的偏特化和范围的偏特化,如上图,左边是数量的偏特化,右边是范围的偏特化
![](https://img.haomeiwen.com/i3138918/619d56c1f3750db8.png)
![](https://img.haomeiwen.com/i3138918/432342d6f3dd5301.png)
![](https://img.haomeiwen.com/i3138918/76ce4f821c82022f.png)
allocator<int>() 是一个临时对象
![](https://img.haomeiwen.com/i3138918/7b7812c45e11f04b.png)
![](https://img.haomeiwen.com/i3138918/6b06dd8f64396a59.png)
![](https://img.haomeiwen.com/i3138918/3bb03b10863d714d.png)
![](https://img.haomeiwen.com/i3138918/d33816656d577b17.png)
![](https://img.haomeiwen.com/i3138918/1accefc526756158.png)
![](https://img.haomeiwen.com/i3138918/04f1b71f92ca9fb7.png)
![](https://img.haomeiwen.com/i3138918/29bb113dea42947d.png)
![](https://img.haomeiwen.com/i3138918/963e668284461928.png)
![](https://img.haomeiwen.com/i3138918/25a588af68bc39fb.png)
![](https://img.haomeiwen.com/i3138918/a8d0d76af5c8f7af.png)
![](https://img.haomeiwen.com/i3138918/9cba2523671c5890.png)
这里的意思是set中包含一个RB_tree;
stack是基于deque实现的
heap是基于vector实现的
priority_queue也是基于vector实现的
![](https://img.haomeiwen.com/i3138918/f1bc22b2cba8f0bd.png)
![](https://img.haomeiwen.com/i3138918/cbc4ae16c643bd70.png)
![](https://img.haomeiwen.com/i3138918/6552f49f96045901.png)
![](https://img.haomeiwen.com/i3138918/00615e01d8cee6a4.png)
LIST ++运算符的重载
注意:copy构造与这里的*运算符重载
运算符重载的标准是模拟整数的操作
![](https://img.haomeiwen.com/i3138918/0566d540357df6bb.png)
![](https://img.haomeiwen.com/i3138918/440363b90e83622c.png)
![](https://img.haomeiwen.com/i3138918/7bb98a4be2668148.png)
![](https://img.haomeiwen.com/i3138918/efbb7e7e55464e03.png)
iterator_category是指迭代器的类别,(1,只能前进 ++; 2,只能后退--; 3,可以跳跃+=3 +=4;)
value_type是指迭代器所指向元素本身的类型 (string int)
difference_type 指两个迭代器距离 需要用什么类型来表现,比如 vector的difference_type 是uint32_t
![](https://img.haomeiwen.com/i3138918/d891e4a09ded944a.png)
指针也是一种迭代器,是一种退化的迭代器
![](https://img.haomeiwen.com/i3138918/2ea5969312288731.png)
既然指针也是一种迭代器,所以如果传进来的类型是指针,那么就无法分辨是普通的迭代器,还是指针类型,所以使用萃取机来中转判断一下,先判断传进来的迭代器是指针类型还是普通的迭代器
![](https://img.haomeiwen.com/i3138918/fe1b65c2472c6dd3.png)
萃取机使用偏特化的方式实现,偏特化出指针类型的iterator_traits,即可
![](https://img.haomeiwen.com/i3138918/c6e08f1f6836f4ee.png)
![](https://img.haomeiwen.com/i3138918/07380f81aebed1f7.png)
![](https://img.haomeiwen.com/i3138918/115bcfd8c8fd7a4e.png)
![](https://img.haomeiwen.com/i3138918/7ae465860b36b204.png)
insert_aux()可能被其他函数调用所以需要再次检查空间
![](https://img.haomeiwen.com/i3138918/dfa929a50b37795d.png)
有可能要被insert()调用,所以前后的元素都要拷贝到新的空间
![](https://img.haomeiwen.com/i3138918/5e8b571ee5caea6a.png)
走偏特化的版本,直接萃取出类型
![](https://img.haomeiwen.com/i3138918/da1ef0003311dc59.png)
![](https://img.haomeiwen.com/i3138918/5a8549077695d485.png)
有一堆复杂的继承关系,好在大小还是12字节
![](https://img.haomeiwen.com/i3138918/4a52928ce01d9a56.png)
走泛化版本的萃取机,获取类型,实现相比4.9变得更为复杂,最终呈现的结果一样
![](https://img.haomeiwen.com/i3138918/8277c3153afa13e3.png)
![](https://img.haomeiwen.com/i3138918/a41af8cb42d7213a.png)
![](https://img.haomeiwen.com/i3138918/1ccd42e9410ec000.png)
![](https://img.haomeiwen.com/i3138918/61e83dbe7d38b9af.png)
deque双向开口,vector单向开口
![](https://img.haomeiwen.com/i3138918/b4c574befc59fec4.png)
![](https://img.haomeiwen.com/i3138918/2dce9d672a4151f1.png)
![](https://img.haomeiwen.com/i3138918/73fe2d952c1267da.png)
![](https://img.haomeiwen.com/i3138918/f85659abea2b0c9b.png)
![](https://img.haomeiwen.com/i3138918/6d6cb674687f0f13.png)
![](https://img.haomeiwen.com/i3138918/e4cc1d9ae05f4a1d.png)
![](https://img.haomeiwen.com/i3138918/c3e2a04545e4cdcc.png)
![](https://img.haomeiwen.com/i3138918/9bdc0f5c3a0c8c6b.png)
![](https://img.haomeiwen.com/i3138918/c57d865bdec95848.png)
![](https://img.haomeiwen.com/i3138918/202ebe2016d6276c.png)
![](https://img.haomeiwen.com/i3138918/8010900e1b10a318.png)
![](https://img.haomeiwen.com/i3138918/a8d94f2d0a6a58fb.png)
![](https://img.haomeiwen.com/i3138918/94792eea4ef6ba96.png)
![](https://img.haomeiwen.com/i3138918/cc606cb742bb0c00.png)
stack queue都不允许遍历,也不提供迭代器
都可选择list 和deque作为底层数据结构 deque更快,性能好
![](https://img.haomeiwen.com/i3138918/c8e70b5b6fd75eb7.png)
关于能选那个容器作为底层数据结构,只要调用的时候底层数据结构都有对应的实现就可以调用
stack可以选择vector作为底层数据结构
queue不可选择vector作为底层结构,但是也并非完全不可以
![](https://img.haomeiwen.com/i3138918/a570b44617e4c8d2.png)
不可选择map或者set作为底层数据结构
![](https://img.haomeiwen.com/i3138918/6769043e43fd162c.png)
![](https://img.haomeiwen.com/i3138918/d4a633d707cbe164.png)
4+4+1=9 对齐之后是12字节,1是空类的大小(compare functor)
![](https://img.haomeiwen.com/i3138918/61f0309144328dcb.png)
identity是gnu c++编译器独有,less是编译器都有
unary_function和binary_function是adapter
![](https://img.haomeiwen.com/i3138918/df9ca89d5bf16342.png)
![](https://img.haomeiwen.com/i3138918/249e9faf83a5a00a.png)
![](https://img.haomeiwen.com/i3138918/b72a32a406b2dfd5.png)
![](https://img.haomeiwen.com/i3138918/383a944534321fde.png)
4.9新版的所有的容器实现中,严格遵守了面向对象oo的设计思想,handle-body的实现模式(桥接模式),对外的类只有接口,具体的实现隐藏在impl指针指向的类中
![](https://img.haomeiwen.com/i3138918/0d0f5d0064295951.png)
![](https://img.haomeiwen.com/i3138918/08caaa3aa1b8a8e3.png)
set可以当作container adapter stack和queue也可以被称作adapter 因为不做事,把事情全部交给底层的数据结构
![](https://img.haomeiwen.com/i3138918/6db2596d2d696d84.png)
vc6没有identity,但是自己实现了一个inner class kfn的东西和identity差不多
![](https://img.haomeiwen.com/i3138918/a48c4cd0cefb7556.png)
![](https://img.haomeiwen.com/i3138918/675389913606b86a.png)
![](https://img.haomeiwen.com/i3138918/d2c9858a86a0025b.png)
这里可以清楚的看到value=key+data 这里用pair对key+data进行了组装
![](https://img.haomeiwen.com/i3138918/08f2fc14611a1a98.png)
![](https://img.haomeiwen.com/i3138918/2632416558d07173.png)
![](https://img.haomeiwen.com/i3138918/3595cd5dcd4588f4.png)
[]会先找到map中当前元素的第一个位置,或者最适和插入该元素的位置,所以这里性能很不错,有优化,
不过insert更加快一点,因为[]最后插入的时候也是调用的insert
![](https://img.haomeiwen.com/i3138918/636b48586131f451.png)
![](https://img.haomeiwen.com/i3138918/6db1b29c9d5e7dbf.png)
![](https://img.haomeiwen.com/i3138918/fba8ce2662514339.png)
bucket数量一般为质数,gnu-C中起始值为53
当元素个数和bucket数量一样是,bucket数量翻倍
bucket数量扩充是扩充为多大是写死的,存在一个static数组中
![](https://img.haomeiwen.com/i3138918/f4316084a2fc20dc.png)
hashtable迭代器中有两个指针 一个指向链表中的元素,一个指向bucket,用来支持遍历操作
![](https://img.haomeiwen.com/i3138918/91c7428553227adc.png)
![](https://img.haomeiwen.com/i3138918/9cb662d7a0de6329.png)
![](https://img.haomeiwen.com/i3138918/6cf29c8e9f024742.png)
![](https://img.haomeiwen.com/i3138918/090feb2f58a5eafe.png)
![](https://img.haomeiwen.com/i3138918/3463871b2af8c2cd.png)
![](https://img.haomeiwen.com/i3138918/8340e9205909ba45.png)
![](https://img.haomeiwen.com/i3138918/b7beb2791d385920.png)
![](https://img.haomeiwen.com/i3138918/361de98d70e506c7.png)
![](https://img.haomeiwen.com/i3138918/0d0c975386d24af2.png)
![](https://img.haomeiwen.com/i3138918/a80ea002379f90e0.png)
![](https://img.haomeiwen.com/i3138918/7b25e9fae53140ed.png)
![](https://img.haomeiwen.com/i3138918/92a5d3e7101fdef7.png)
模板函数可以和普通函数重名?这种不算特化,叫重载?
调用函数时会进行严格的类型匹配,但是模板函数不会进行自动类型转换,而普通函数具有隐式的类型转换。
其调用顺序应该是:
- 首先寻找参数完全匹配的普通函数,如果找到了就调用它
- 若1不存在则寻找一个函数模板,将其实例化,产生一个匹配的模板函数,若找到了,就调用它
- 若1,2都皆不存在,会寻找低一级的对函数的重载方法,例如通过类型转换可产生参数匹配等,若找到了,就调用它
- 若1,2,3均未找到匹配的函数,则是一个错误的调用
参考
![](https://img.haomeiwen.com/i3138918/bd645875c016f653.png)
![](https://img.haomeiwen.com/i3138918/053a3cf22fd5db88.png)
获取c++语言本身给类型的名字 typeid().name ,得到的是编译器给这个类型的名字
![](https://img.haomeiwen.com/i3138918/c31f6d2330825c69.png)
三个版本接口一样
这里有一个神奇继承关系,itertor是一个只有内嵌类型(typedef)的类,没有function,没有data,ostream_iterator继承之后,也只是为了继承iterator中的内嵌类型
![](https://img.haomeiwen.com/i3138918/97b52aa75ceb9523.png)
![](https://img.haomeiwen.com/i3138918/52f2134156726010.png)
根据迭代器的类型,选择不同的计算迭代器之间距离的方法
![](https://img.haomeiwen.com/i3138918/6fd3ce2e0416bc5a.png)
根据迭代器的类型,选择 +n 前进 (或者-n 后退)的方法
![](https://img.haomeiwen.com/i3138918/eea4ad5944597faa.png)
根据迭代器的类型选择copy的方法,总是会选择最合适的办法去做拷贝动作
type traits .....? 使用type traits判断是否has trival operate=(拷贝赋值到底重不重要) 后面会讲---
![](https://img.haomeiwen.com/i3138918/023793430d7d3da6.png)
根据迭代器的类型选择destroy的方法
![](https://img.haomeiwen.com/i3138918/55b0512caaee5b1f.png)
根据迭代器的类型选择destroy的方法
![](https://img.haomeiwen.com/i3138918/c6fbd1d996b6ecae.png)
output_iterator write only
input_iterator read only
stl有针对传入不同迭代器进行专门的处理
![](https://img.haomeiwen.com/i3138918/23d33b08537acc40.png)
因为算法源码都是模板实现,所以理论上不区分迭代器类型,但是有相应的暗示,如上图所示,如果传入的迭代器类型不符合要求,可能会编译失败
![](https://img.haomeiwen.com/i3138918/e1dcd7dcdf74be0f.png)
![](https://img.haomeiwen.com/i3138918/07fe55caaa320fa1.png)
![](https://img.haomeiwen.com/i3138918/3b27a8e6becf33a9.png)
![](https://img.haomeiwen.com/i3138918/476faf567a729b49.png)
![](https://img.haomeiwen.com/i3138918/915865628abc5746.png)
![](https://img.haomeiwen.com/i3138918/f01cd371a3787655.png)
![](https://img.haomeiwen.com/i3138918/55195c70679dd15e.png)
![](https://img.haomeiwen.com/i3138918/ba24f59d4230128f.png)
![](https://img.haomeiwen.com/i3138918/2dbe95c939bed3b4.png)
![](https://img.haomeiwen.com/i3138918/4bf7502730cd8ce9.png)
![](https://img.haomeiwen.com/i3138918/8d31f1e695eff340.png)
![](https://img.haomeiwen.com/i3138918/efbf271f6149d624.png)
![](https://img.haomeiwen.com/i3138918/c4f7ba923ec98fb6.png)
stl中多处使用内嵌内型,如下,子类继承父类之后拥有同样的定义
template <class arg, class result>
struct unary_function{
typedef arg argument_type;
typdef result result_type;
};
![](https://img.haomeiwen.com/i3138918/8a145f6ce4fa5289.png)
adapter都是包含的关系,adapter适配器的意思就是内涵一个东西,然后对这个东西进行改造,如下图
![](https://img.haomeiwen.com/i3138918/511dd6cdc15ae98d.png)
stack queue 内含一个deque,然后进行改造,比如push_back()改名为push()
![](https://img.haomeiwen.com/i3138918/96e1b18847e833bc.png)
多处使用模板编程的技巧,typedef内嵌类型
![](https://img.haomeiwen.com/i3138918/924b2712aabaa671.png)
![](https://img.haomeiwen.com/i3138918/fd309704cfcff469.png)
所以std::bind是一个适配器 非常有趣
std::bind返回值是function object
![](https://img.haomeiwen.com/i3138918/c6f7442f811edf90.png)
bind用法详解 可以绑定4种东西,返回是function object
![](https://img.haomeiwen.com/i3138918/bdd813d1b8c5a563.png)
rbegin() rend()也都是适配器
![](https://img.haomeiwen.com/i3138918/be264789c1c97e40.png)
接管赋值操作,将普通赋值操作变成insert操作
![](https://img.haomeiwen.com/i3138918/9f6a7ffa090d4932.png)
这里有一个神奇的示例,建议测试一下,详细看下代码!!!
for(int i=0; i<10; ++i){
v.push_back(i*10);
}
std::ostream_iterator<int> out_it(std::cout, ",");
std::copy(v.begin(), v.end(), out_it);
![](https://img.haomeiwen.com/i3138918/6727e9957d14798b.png)
double v1, v2;
std::cout<<"input two valus: "<<std::endl;
std::istream_iterator<double> eos;
std::istream_iterator<double> iit(std::cin);
if(iit!=eos) v1=*iit;
++iit;
if(iit!=eos) v2=*iit;
std::cout<<"v1: "<<v1<<"v2: "<<v2<<"\n";
![](https://img.haomeiwen.com/i3138918/5a110c3e9a426b43.png)
istream_iterator构造的时候 已经在等待输入!!!!!!!!!!!!!
![](https://img.haomeiwen.com/i3138918/6e6483bea5a161b4.png)
虚线框起来的是上面函数的类型
![](https://img.haomeiwen.com/i3138918/6798baf07e351fe8.png)
很多技巧:
1 变参模版函数参数,拆分
2 同名函数递归调用
3 pass by reference seed值
4 最后的hash code是seed值
5 seed计算方式采用了黄金比例计算公式,详见下图
![](https://img.haomeiwen.com/i3138918/72bc1e88c72d4ea3.png)
![](https://img.haomeiwen.com/i3138918/908936116f8ec830.png)
![](https://img.haomeiwen.com/i3138918/0bf491a6d6228292.png)
![](https://img.haomeiwen.com/i3138918/900f417c7eff032c.png)
![](https://img.haomeiwen.com/i3138918/bb9d8fd0e6b4d372.png)
![](https://img.haomeiwen.com/i3138918/d1d9a239f6034a77.png)
tuple的一些神奇用法
1 tie
2 tuple_size
3 tuple_element
4 make_tuple
5 get<0>()
![](https://img.haomeiwen.com/i3138918/a6a44a8777a48c7a.png)
这里同样使用了很多技巧, 关键的技巧就是variadic template 可变参数模板 (自动递归)
1 私有继承
2 一层层剥离模板参数列表
3 tail返回值,this会被强转
![](https://img.haomeiwen.com/i3138918/068c55b88574fe72.png)
2.9版本type_traits 需要自己补充自定义类型的的萃取机制
![](https://img.haomeiwen.com/i3138918/e8c052a9186dd439.png)
4.9 新版本中定义了一大堆萃取机,不需要补充自定义类型的萃取机制
![](https://img.haomeiwen.com/i3138918/7cc9d7cd41a45d3c.png)
![](https://img.haomeiwen.com/i3138918/0a7b54b295760104.png)
![](https://img.haomeiwen.com/i3138918/38d8d36bf2382e05.png)
![](https://img.haomeiwen.com/i3138918/99ed61a36817b037.png)
![](https://img.haomeiwen.com/i3138918/a2664e9ff860869d.png)
![](https://img.haomeiwen.com/i3138918/1fe0e3a5d36ee108.png)
![](https://img.haomeiwen.com/i3138918/c068b8d4c17c6aa6.png)
![](https://img.haomeiwen.com/i3138918/0bbca13bf78c1336.png)
![](https://img.haomeiwen.com/i3138918/05c274b5ce44b1f8.png)
![](https://img.haomeiwen.com/i3138918/187be884be49fb99.png)
![](https://img.haomeiwen.com/i3138918/fcaeb50941b551fa.png)
编译器 在其中实现了一些函数,因为编译器知道一个类是否具有拷贝构造,拷贝赋值,是不是一个类型等这些问题
![](https://img.haomeiwen.com/i3138918/c77e531758cfc8e1.png)
![](https://img.haomeiwen.com/i3138918/931a411baa4e9d42.png)
2.9版本中,cout就是ostream对象对操作符的重载“<<”
![](https://img.haomeiwen.com/i3138918/6eb582fae17b68be.png)
同样4.9版本中,cout就是ostream对象对操作符的重载“<<”
![](https://img.haomeiwen.com/i3138918/5fa560afc87bf5ce.png)
cctor是copy构造 mctor是移动构造 后者性能强很多;
具体差多少跟当前内存情况有关
![](https://img.haomeiwen.com/i3138918/564f1610b05f64b0.png)
![](https://img.haomeiwen.com/i3138918/f4b5667037e4e866.png)
![](https://img.haomeiwen.com/i3138918/e857582a56b5bd40.png)
![](https://img.haomeiwen.com/i3138918/d0a1bb893175f96d.png)
![](https://img.haomeiwen.com/i3138918/627df95a1e9b776b.png)
![](https://img.haomeiwen.com/i3138918/af55af30257793b1.png)
所以移动语意其实是浅拷贝,所以需要注意的是:
使用移动语意之后,原来的object是不可使用的
![](https://img.haomeiwen.com/i3138918/badc1d31784f8ed1.png)
![](https://img.haomeiwen.com/i3138918/1e35f1d8e7f316ff.png)
这个是深copy
![](https://img.haomeiwen.com/i3138918/4340b92a51278e50.png)
这个是浅copy
![](https://img.haomeiwen.com/i3138918/c4599bc2eadbda7c.png)
以上是string的构造函数,拷贝构造,移动构造
网友评论