【无标题】C++3:拷贝构造以及编译器优化 this指针我们在创建变量时如果名字与类的普通成员方法名字相撞那我们应该如何区分到底是把哪个值赋给谁呢这时候就引出this指针可以区别classTest{public:intnum;// 成员变量voidsetNum(intnum){// this-num类自身的成员变量// num传入的形参局部变量this-numnum;}由此我们引出this指针定义你创建一个类的实例对象电脑会在内存里给它单独划分一块地盘对象调用自己的成员函数时编译器会自动把这个对象的内存地址打包成this偷偷传给成员函数在成员函数内部this就代表 “正在干活的这个对象自己”。总之谁调用这个成员函数this就指向谁。△ this指针专门指向调用该方法的对象拷贝构造咱们在重新构造一个和之前某一个一摸一样的对象时就叫拷贝构造。但是拷贝构造分为浅拷贝与深拷贝。默认拷贝构造视为浅拷贝浅拷贝就例如照着蛋糕 A 的样子复刻一块配料、造型完全一致的新蛋糕 B全程不用重新走一遍基础配料初始化。classPerson{public:intage;// 手动实现默认风格的拷贝构造Person(constPersonp){agep.age;}};intmain(){Personp1(18);// 普通构造造出第一个对象Personp2(p1);// 调用拷贝构造照着p1复制出全新p2return0;} 为什么需要深拷贝呢 浅拷贝只是单纯把指针变量里存的地址原样复制一份。 两个对象的指针指向同一块堆内存 对象 A 释放内存delete对象 B 的指针变成野指针等到 B 析构再次执行delete程序直接崩溃重复释放同一块内存。 深拷贝如下 cpppublic:intage;char*name;// 堆区动态开辟的字符串必须深拷贝Person(constPersonp){agep.age;//自己新开一块堆内存而不是直接复制指针地址namenewchar[strlen(p.name)1];strcpy(name,p.name);}// 析构函数释放堆内存~Person(){delete[]name;}intmain(){Personp1(20,小明) Person p2 p1;return0;}那什么时候要深拷贝呢1… 类内包含手动 new/malloc 在堆上开辟的内存2. 独占资源赋值per1per2看似是赋值其实调用了per1的operator函数//per1per2Personoperator(constPersonp){if(thisp){return*this;//防止自己给自己赋值}delete[]this-name;// 拷贝普通成员this-agep.age;//this-namenewchar[strlen(p.name)1];strcpy(this-name,p.name);// 返回自身引用支持连续赋值 p1p2p3return*this;什么是explicit在未加关键字前会出现隐式转换加完之后写Person p 18; test(20);会报错但是可以// 方式1Personp(18);// 方式2Person pPerson(18);// 方式3test(Person(20));C编译器对临时对象的优化1.使用临时对象拷贝构造同类型新对象临时对象被优化使用构造临时对象的方式直接构造新对象即可例如person per4(Person(z张飞23‘M’))就不会构造临时对象直接构造出来相当于per4“张飞”23‘M’2.但是如果你进行赋值的话那么临时对象不会被优化因为一旦优化就无法对新对象进行赋值PersonGetperson(person per){constchar*nameper.getName();intageper.getAge();charsexper.getSex();PersontmpPer(name,age,sex);returntmpPer;}intmain(){Personper1(x““22”“m”);Person per2;per2Getperson(per1);per2.show;}以上这段代码我们可以理解为从main函数开始分析先进行per1的三个参数构造再进行per2的默认构造然后实参到形参是一个拷贝构造编译器直接优化不再拷贝构造tmpPer生成一个main函数栈上的临时对象然后对per2进行赋值操作PersonGetperson(person per){constchar*nameper.getName();intageper.getAge();charsexper.getSex();PersontmpPer(name,age,sex);returntmpPer;}intmain(){Personper1(x““22”“m”);Person per2Getperson(per1);per2.show;}我们从Person per2Getperson(per1);开始分析本来的顺序Getperson 值接收参数把 per1 拷贝一份得到栈上形参 per在 Getperson 函数自身栈空间里正常构造局部对象 tmpPer调用普通构造函数把 tmpPer 拷贝构造一份放到 main 栈的返回值临时对象再用这个临时对象拷贝构造 main 里的 per2函数退出销毁 tmpPer、形参 per最后析构临时、per1、per2。但是编译器优化时直接就把tmpPer当成per2进行常规构造心得总结本节课主要内容为this指针拷贝构造赋值函数C编译器优化我认为this指针指向被调用方法的对象是一个很重要的点在此之前我一直以为this指针是每个参数都拥有的其次拷贝构造中我认为为什么会出现深拷贝这种问题是很重要的只有知道为什么需要深拷贝我们才能了解深拷贝的底层原理C编译器优化中比较难的我认为是何时临时对象会进行赋值而何时不能够省略临时对象这需要再琢磨琢磨以上包含我这节课所认为重点核心难点以及还未攻克的难题