当前位置: 首页 > news >正文

【无标题】C++3:拷贝构造以及编译器优化

this指针

我们在创建变量时,如果名字与类的普通成员方法名字相撞,那我们应该如何区分到底是把哪个值赋给谁呢?这时候就引出this指针,可以区别

classTest{public:intnum;// 成员变量voidsetNum(intnum){// this->num:类自身的成员变量// num:传入的形参局部变量this->num=num;}

由此我们引出this指针定义
你创建一个类的实例(对象),电脑会在内存里给它单独划分一块地盘;
对象调用自己的成员函数时,编译器会自动把这个对象的内存地址打包成this,偷偷传给成员函数;
在成员函数内部,this就代表 “正在干活的这个对象自己”。
总之:谁调用这个成员函数,this就指向谁
△ this指针专门指向调用该方法的对象

拷贝构造

咱们在重新构造一个和之前某一个一摸一样的对象时,就叫拷贝构造。
但是拷贝构造分为浅拷贝与深拷贝。
默认拷贝构造视为浅拷贝,浅拷贝就例如照着蛋糕 A 的样子,复刻一块配料、造型完全一致的新蛋糕 B,全程不用重新走一遍基础配料初始化。

classPerson{public:intage;// 手动实现默认风格的拷贝构造Person(constPerson&p){age=p.age;}};intmain(){Personp1(18);// 普通构造,造出第一个对象Personp2(p1);// 调用拷贝构造,照着p1复制出全新p2return0;}`` 为什么需要深拷贝呢? 浅拷贝只是单纯把指针变量里存的地址原样复制一份。 两个对象的指针指向同一块堆内存: 对象 A 释放内存delete;对象 B 的指针变成野指针;等到 B 析构再次执行delete,程序直接崩溃(重复释放同一块内存)。 深拷贝如下 ```cpppublic:intage;char*name;// 堆区动态开辟的字符串,必须深拷贝Person(constPerson&p){age=p.age;//自己新开一块堆内存,而不是直接复制指针地址name=newchar[strlen(p.name)+1];strcpy(name,p.name);}// 析构函数释放堆内存~Person(){delete[]name;}intmain(){Personp1(20,"小明"); Person p2 (p1);return0;}

那什么时候要深拷贝呢?
1… 类内包含手动 new/malloc 在堆上开辟的内存
2. 独占资源

赋值

per1=per2看似是赋值,其实调用了per1的operator=函数

//per1=per2Person&operator=(constPerson&p){if(this==&p){return*this;//防止自己给自己赋值}delete[]this->name;// 拷贝普通成员this->age=p.age;//this->name=newchar[strlen(p.name)+1];strcpy(this->name,p.name);// 返回自身引用,支持连续赋值 p1=p2=p3return*this;

什么是explicit?
在未加关键字前会出现隐式转换
加完之后写Person p = 18; test(20);
会报错,但是可以

// 方式1Personp(18);// 方式2Person p=Person(18);// 方式3test(Person(20));

C++编译器对临时对象的优化

1.使用临时对象拷贝构造同类型新对象,临时对象被优化
使用构造临时对象的方式,直接构造新对象即可
例如person per4(Person("z张飞",23,‘M’))就不会构造临时对象,直接构造出来相当于per4(“张飞”,23,‘M’)
2.但是如果你进行赋值的话,那么临时对象不会被优化,因为一旦优化就无法对新对象进行赋值

PersonGetperson(person per){constchar*name=per.getName();intage=per.getAge();charsex=per.getSex();PersontmpPer(name,age,sex);returntmpPer;}intmain(){Personper1("x“,“22”,“m”);Person per2;per2=Getperson(per1);per2.show;}

以上这段代码我们可以理解为,从main函数开始分析,先进行per1的三个参数构造,再进行per2的默认构造,然后实参到形参是一个拷贝构造,编译器直接优化(不再拷贝构造tmpPer),生成一个main函数栈上的临时对象然后对per2进行赋值操作

PersonGetperson(person per){constchar*name=per.getName();intage=per.getAge();charsex=per.getSex();PersontmpPer(name,age,sex);returntmpPer;}intmain(){Personper1("x“,“22”,“m”);Person per2=Getperson(per1);per2.show;}

我们从Person per2=Getperson(per1);开始分析:本来的顺序Getperson 值接收参数,把 per1 拷贝一份得到栈上形参 per;在 Getperson 函数自身栈空间里,正常构造局部对象 tmpPer(调用普通构造函数);把 tmpPer 拷贝构造一份放到 main 栈的返回值临时对象;再用这个临时对象,拷贝构造 main 里的 per2;函数退出销毁 tmpPer、形参 per,最后析构临时、per1、per2。但是编译器优化时,直接就把tmpPer当成per2进行常规构造

心得总结

本节课主要内容为this指针,拷贝构造,赋值函数,C++编译器优化,我认为this指针指向被调用方法的对象是一个很重要的点,在此之前我一直以为this指针是每个参数都拥有的,其次拷贝构造中我认为为什么会出现深拷贝这种问题是很重要的,只有知道为什么需要深拷贝我们才能了解深拷贝的底层原理,C++编译器优化中比较难的我认为是何时临时对象会进行赋值而何时不能够省略临时对象,这需要再琢磨琢磨,以上包含我这节课所认为重点核心难点以及还未攻克的难题

http://www.jsqmd.com/news/1344925/

相关文章:

  • 本地批量用工人力公司有哪些?2026 区域服务商**快速匹配指南 - 运营老默复盘
  • 2026北京美术艺考指南:按目标院校适配的选择路径 - 阿辰运营笔记
  • UE5升级MSB3073错误全解析:从构建系统冲突到Live Coding死锁的根治方案
  • 云GPU实战指南:从零搭建深度学习环境到高效训练部署
  • VRoid角色导入Unity全流程:Blender减面与材质优化实战指南
  • 如何用嘎嘎降AI处理社会学论文:社会学毕业论文降AI免费4.8元知网维普达标完整操作教程
  • 基于大模型与OpenClaw构建智能安全日志分析系统实战
  • 耐火型母线槽工程选型要点:耐火指标、结构设计与检测报告核查
  • GLM、Kimi、DeepSeek 怎么选?MonkeyCode 的多模型切换,让 AI 编程成本省一半
  • Unity UI Dropdown组件深度解析:五大常见问题与性能优化实战
  • AI CLI工具:将Claude能力无缝集成到命令行工作流
  • 角色插画创作全流程解析:从构思到完稿的实战指南
  • 2026年兰州商标注册代办机构选择参考与甘肃ITSS三级资质办理指南 - 优质品牌商家
  • 无人机高精度建筑物分割 遥感地形分割
  • 2026北京高考美术培训观察:小班制与精细化教学的客观对比 - 增长观测局
  • 深度探索WiGLE WiFi Wardriving:Android无线网络探测与数据分析实战指南
  • STM32 GPIO深度解析:从硬件架构到实战配置与避坑指南
  • Unity游戏开发中的命令模式:从解耦到高级应用实战
  • PADS实战:四层板HDMI高速PCB设计全流程解析与信号完整性保障
  • 如何用嘎嘎降AI处理计算机科学论文:CS毕业论文降AI4.8元知网达标完整操作教程
  • 从文档能力到 Agent Skill:BaseMetas IDP 文件预览、格式转换与内容处理解析
  • STM32 FLASH闪存原理与实战:从基础操作到IAP应用
  • Windows安全中心空白界面修复:从服务重置到系统文件修复的完整指南
  • 西瓜视频去水印用什么工具?个人收藏向实用教程 - 免费软件工具方法教程
  • 从RAG到知识内化:大模型私有化部署的技术演进与实战指南
  • 开源桌面应用部署指南:从环境配置到功能验证的完整避坑手册
  • 找石家庄不干胶印刷厂家联系方式参考这份指南石家庄宏达印刷 - 热点品牌推荐
  • 沙盒工具实现程序多开与隔离保护系统
  • 10分钟零代码搭建Coze工作流智能体:从入门到实战
  • Android开发实战:Java与Kotlin代码互转的核心技巧与避坑指南