string vector
改成上图才能正确识别、改成上图才能正确识别拷贝构造 现代写法下图左传统 下图右现代this 指向当前正在构造 / 操作的对象实例。成员变量也如左图一样this 指向的对象调用对应类的成员函数并传入参数利用string tmps.str会调用接收char*类型的构造函数字符指针构造不是默认构得到tmp(帮我们完成原来我们手动需要完成的数据处理),上图this是s2的。调用方s1是传入函数的参数s代码进行了交换如果内置类型没有初始化是随机值交换给tmp会有问题。因为tmp出了作用域后会析构释放随机野指针 → 程序崩溃。所以这里将成员变量初始化。tmp销毁空指针编译器在编译阶段就计算好了这个类单个实例的总占用字节。在创建使用构造函数该类的对象之前不管是栈、堆、全局区都必须已经分配好完整的单个实例的总占用字节这是对象的存储载体。freedelete,delete[]空时直接返回不会报错赋值 现代写法调用接收char*类型的构造函数和拷贝构造都行拷贝构造参数必须是引用。如果是传值传参不是引用那么会调用拷贝构造拷贝构造又会调用传值传参无穷递归。赋值参数不用必须是引用是传值传参那么会调用拷贝构造正好将s3拷贝构造给tmp,然后直接交换即可s1原本的空间就需要释放交还给tmptmp出了作用域后会自动调用析构函数swap自己手动模拟 库里模板以交换两个自定义对象为例直接套库里模板会有三次深拷贝伴随开空间拷贝数据析构等代价太大。交换内置类型或无深拷贝对象就行自己手动模拟的也是套库里模板只不过交换的类型都是内置类型效率明显提升库里还有一个全局swap函数与模板同名。所以出现swap情况下优先调用该函数。一、标准库提供的全局std::swap(string x, string y)内部实现就是一行void swap(string x, string y) { x.swap(y); }标准库内部已经给std::string写好了类内成员函数swap()同时库中预实现了全局重载std::swap(string, string)你直接写代码std::swap(s1, s2)就能调用底层自动执行s1.swap(s2)x.swap(y)代表用对象 x 调用自身的成员 swap 函数传入对象 y。二、标准库里没有为你的自定义string类提前写好swap 重载如果什么都不写直接调用std::swap(s1,s2)会触发通用模板templatetypename T void swap(T a, T b) { T temp a; // 完整拷贝整个字符串复制堆上所有字符低效 a b; b temp; }性能极差违背 swap 轻量化设计。三、想要让std::swap(s1,s2)高效交换你的自定义 string必须自己实现类内成员 swap// 写在你的自定义string类里面 void swap(string s) { std::swap(_str, s._str); std::swap(_size, s._size); std::swap(_capacity, s._capacity); }只要有这个成员函数调用std::swap(s1,s2)时编译器依靠 ADL 查找规则优先调用该函数会自动执行s1.swap(s2)编译器优先去bit命名空间、string类内调用模拟实现的成员函数 swap和标准文档描述行为一致只交换三个内置变量O (1) 开销