事情是这样的:

博主今天回看以前实现过的string,当时就遇到了一个bug:

可见博主当时的破防。因为最近在集中复盘C++初阶部分,就有点好奇年轻的时候自己写的模拟string是什么样。没想到给我自己留了个bug。


现在来细看这个场景:为了测试自己写的赋值拷贝现代写法效果,有了这个函数。

	void test11(){//现代构造的写法string s("helloworld");string s2(s);// 现代拷贝构造cout << s2 << endl;string s3("cherry magic");s2 = s3;// 现代赋值拷贝cout << s2 << endl;}

当来到165行时——即我打算让s3赋值给现有的对象s2,此时自然要调用我亲手写的赋值拷贝

图1 调试到165行
图2 亲手写的赋值拷贝

当我按F11,企图跳进operator=里时,却是来到了拷贝构造这里。

嗯?此举何意啊——正常意料:我亲手写的赋值拷贝operator=传的参数是传值传参(传值(自定义类型string)传参都要雷打不动先拷贝构造一份)

图2 继续下一步,来到了string的拷贝构造函数

没错,拷贝构造我也写出了现代写法——避免这里长篇大论,现代写法我几句话说个大概,说不定读者看完就能上手写。

string tmp(s.c_str());//tmp建立在当前函数栈上,等当前函数结束,函数栈帧被销毁,生命周期也结束了。

当这句话执行完,tmp就是存在于当前栈上,但内容是拷贝s的string对象。我们拷贝构造函数的目的,就是让当前的*this(未构造的对象)拷贝传入对象s的内容,完成对象初始化。

无论如何,当拷贝构造函数结束,*this是完全实例化,tmp却要走向独属它的落幕(因为tmp是string自定义类型对象,它自动会调用析构完成资源释放)。

tmp拷贝完了,*this还没拷贝。怎么办?把*this有个大胆的想法——

swap(tmp);// 完整写 this->swap(tmp); 或者 (*this).swap(tmp);

看我的批注:*this用自己的成员函数将tmp和自己交换——交换了拷贝的内容。*this就这么轻轻一换完成了拷贝构造,tmp就拿着本来无用的信息去析构了。


我们继续按F11,等此次拷贝构造结束——跳入operator=的参数就构造完成,我们就进入operator=看看问题出在哪。

图3:先拷贝构造
图4:string tmp(s.c_str())已然完成
图5:*this拷贝构造完成

tmp此时该走向独属于它的落幕——身为string家中的长(栈)子,它有自己的使命(*this是次子(bushi

图6:tmp开始析构
图7:首先析构的——tmp的成员变量_str指向堆上的资源
图8:报错了,牛

其实刚刚那一步,可能有读者看出不对劲了。tmp交换过来的内容,应该是完全没被初始化的——怎么可能会有需要的释放的资源?那个_str也是生得奇怪——恰好是随机值,躲过了判空检查,所以避无可避地执行了delete[] _str;

我今天在改这个代码的时候,其实没注意到这点:因为出了构造函数完成了参数的拷贝构造,我想着此时该进入operator=了。直接按下了F10——跳过了tmp的析构,直接出现了这一幕。

所以下意识判断是operaor=的问题:这也是为什么我会当时写下这句判断——

图9:看得出来年轻时候第一次写现代写法,很没底气。一报错就怀疑上了

真相是什么?

今天在改代码的时候,我发现因为*this天生生得潦草,_str这个指针怎么生都是随机值——所以tmp换到它的内容,必走析构里的delete[] _str;——这件事让我很是苦恼,知道哪里出问题了,却是下不了手。

有没有什么方法?有的,只是我忘了(我忏悔)

初始化列表

我今天也是开眼了,拷贝构造也是构造。只要是构造函数,类型的成员变量就会走初始化列表——初始化列表存在的意义就是对成员变量定义。

身为变量,有了声明自然要有定义。所以不管显示写初始化列表与否,成员变量都会被定义(即成员变量都会走初始化列表)。初始化列表是很客观的存在,不是我们不写就不存在的。

如果显示写初始化列表,相应成员变量都会被规定的值初始化;
如果不显示写,可以在声明的位置给出缺省值——没错,这里的缺省值就是给未显示写在初始化列表的成员进行定义

  • 如果声明都不给缺省值了,那编译器表示:“那我随意了”——对于内置类型,编译器会给它随机值(取决于编译器,行为不确定);对于自定义类型,会去调用它的默认构造(如果没有默认构造,会编译报错)

想起来了,我再看我的string成员变量声明——果然没有声明值,而且刚刚的拷贝构造也没显示初始化列表(完美地避开正确初始化机会)

图10:string类的成员变量声明
图11:加上缺省值,静态成员变量在其他地方定义了

再看效果:

图12:成功运行

我发现AI摘要比我写得完整,但我想没我写得有趣:(对只是我想)
摘要:博主复盘自己早期实现的string类时,发现了一个隐藏bug。问题出现在拷贝构造函数的现代写法中:当交换临时对象tmp和未初始化的*this时,由于未显式初始化_str成员变量,导致析构时delete了一个随机地址。通过给成员变量添加缺省值,解决了这个因未初始化引发的未定义行为。文章详细记录了调试过程,揭示了C++构造函数初始化列表的重要性,以及显示初始化成员变量的必要性。最终修复方案是为string类的成员变量添加了缺省值声明,使程序得以正确运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/923541.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/923541.shtml
英文地址,请注明出处:http://en.pswp.cn/news/923541.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习-Bagging

Bagging-Bootstrap AGGrgratING Bagging并行训练n个基本学习器&#xff08;base learner&#xff09;通过平均所有学习器的输出&#xff08;回归&#xff09;或主投票&#xff08;分类&#xff09;做决策每个模型是用在训练集上通过bootstrap采样得到的新的数据集进行训练得到的…

Unity3D Shader 入门知识

Unity3D Shader 入门知识详解。 Unity3D Shader 入门知识 Shader&#xff08;着色器&#xff09;对很多 Unity 初学者来说像是“黑魔法”。 实际上&#xff0c;Shader 并没有那么神秘&#xff0c;它本质上就是一段运行在 GPU 上的小程序&#xff0c;用来控制 屏幕上每个像素的颜…

【面试之Redis篇】主从复制原理

从面试的角度来解释 Redis 主从复制原理&#xff0c;按照“总-分-总”的结构&#xff0c;清晰地阐述其核心概念、工作流程和关键要点&#xff0c;这能体现出你不仅知道是什么&#xff0c;还理解为什么以及如何应对相关问题。总览&#xff1a;一句话定义 面试官您好&#xff0c;…

数据库开启ssl

数据库&#xff1a;阿里云rds 系统&#xff1a;centos 需要修改的&#xff1a;nacos连接项目连接本地navicat连接 重点&#xff1a;为了兼容本地和服务器&#xff0c;ssl证书路径由原来的绝对路径换成环境变量参数&#xff0c;所以有步骤4 文章目录步骤1 阿里云步骤2 navicat…

Redis 事件驱动与多路复用源码剖析

Redis 事件驱动与多路复用源码剖析1. 前言 Redis 是 单线程 I/O 多路复用 的典型代表。 它并不是多线程处理请求&#xff0c;而是依赖 事件驱动&#xff08;event-driven&#xff09;模型&#xff0c;在一个线程内高效管理海量连接。 核心组件&#xff1a; ae.c&#xff1a;事…

VR煤矿实训系统相较于传统煤矿培训方式的独特优势​-广州华锐互动

高度逼真&#xff0c;沉浸体验​VR煤矿实训系统运用先进的3D建模、动态仿真技术&#xff0c;对煤矿井下的复杂环境进行1:1还原。从幽深的巷道、运转的采煤设备&#xff0c;到潮湿的空气、昏暗的灯光&#xff0c;甚至细微的煤尘颗粒&#xff0c;都能逼真呈现。使用者戴上VR设备后…

javaweb XML DOM4J

XMLXML作用就是配置文件&#xff0c;properties使用不了较复杂的需求&#xff0c;xml应运而生配置文件对比 xml更方便tips1:新建resources目录&#xff0c;并将src中的jdbc.properties移到resourcs中&#xff0c;并且右键标记为源代码根目录&#xff0c;这样运行src时就会和pro…

多模态视频理解领域 Benchmark 与 Leaderboard 整理

多模态视频理解是当前人工智能领域的研究热点&#xff0c;其核心目标是让模型像人类一样&#xff0c;综合视频中的视觉、听觉&#xff08;部分场景&#xff09;及文本信息&#xff0c;实现对视频内容的深度感知、理解与推理。为客观评估模型性能&#xff0c;行业内涌现了众多权…

18j621-3通风天窗图集pdf(免费高清版)

18j621-3通风天窗已经替代05j621-3通风天窗图集成为目前比较通用的建筑屋顶通风选型重要参考标准&#xff0c;18j621-3图集是对前图集的优化和革新&#xff0c;在18j621-3图集中新增了TC8圆拱型电动采光天窗&#xff0c;丰富了屋面通风排烟设备的选型。在18j621-3天窗图集中&am…

LawGPT:基于中文法律知识的大模型

本文转载自&#xff1a;https://www.hello123.com/lawgpt ** 一、⚖️ LawGPT&#xff1a;中文法律界的 “AI 法助”&#xff0c;啃透了 15 万份判决书&#xff01; LawGPT 是一系列专攻中文法律知识的开源大模型&#xff0c;在通用中文基座&#xff08;如 ChatGLM&#xff0…

用 go-commons 快速写一个监控 CPU/内存的 Exporter

欢迎加入开源项目&#xff0c;提你的 mr Go Commons&#xff1a;Golang 开发者的常用工具集&#xff0c;一站式解决常见需求 在 Go 语言的开发过程中&#xff0c;你是不是经常遇到这样的情况&#xff1a; 想要做点小功能&#xff0c;却得从零写起&#xff0c;或者到处找三方…

KingbaseES客户端工具Ksql使用全指南:从安装到高级操作

引言 在国产数据库蓬勃发展的今天&#xff0c;KingbaseES凭借其自主可控、高性能、高可用的特性&#xff0c;已成为政务、金融、能源等关键领域的首选数据库。而作为其配套的命令行工具&#xff0c;Ksql更是DBA和开发人员的“瑞士军刀”——它不仅能高效执行SQL查询&#xff0c…

【LeetCode - 每日1题】可以输入的最大单词数

🌈 个人主页:(时光煮雨) 🔥 高质量专栏:vulnhub靶机渗透测试 👈 希望得到您的订阅和支持~ 💡 创作高质量博文(平均质量分95+),分享更多关于网络安全、Python领域的优质内容!(希望得到您的关注~) 🌵目录🌵 难度 ⭐⭐ 题目回顾 ✅解题思路 💖概述 💓核心…

3227. 字符串元音游戏

3227. 字符串元音游戏 题目链接&#xff1a;3227. 字符串元音游戏 代码如下&#xff1a; class Solution { public:bool doesAliceWin(string s) {return ranges::any_of(s, [](char c) {return c a || c e || c i || c o || c u;});} };

微信小程序坐标位置使用整理(四)map组件

一、地图上标点&#xff0c;marker 1.wxml <map id"map" scale"9" class"map"markers"{{markers}}" longitude"{{longitude}}" latitude"{{latitude}}" show-location"{{true}}"><cover-vie…

Parlant框架深度技术解析:革命性AI代理行为建模引擎

引言 在人工智能快速发展的今天&#xff0c;AI代理&#xff08;Agent&#xff09;技术已经成为连接人工智能与实际应用场景的重要桥梁。然而&#xff0c;传统的AI代理开发面临着诸多挑战&#xff1a;提示词工程的复杂性、行为不可预测性、工具调用的不确定性等问题严重制约了AI…

AI重构车载测试:从人工到智能的跨越

目录 一、AI 在车载测试中的核心价值 二、AI 在车载测试的具体应用场景 (一)自动驾驶测试:AI 解决 “场景覆盖” 与 “决策可靠性” 难题 (二)车机系统测试:AI 优化 “交互体验” 与 “功能稳定性” (三)车载硬件测试:AI 实现 “故障预测” 与 “精准校准” (四)功能…

从职责划分看架构:MVC 的 Controller 与 MVVM 的 ViewModel 差异

深入浅出&#xff1a;前端MVC与MVVM架构模式&#xff0c;你真的懂了吗&#xff1f;✨ 序言 各位前端的“程序猿”和“程序媛”们&#xff0c;大家好&#xff01;&#x1f44b; 在前端开发的江湖中&#xff0c;MVC和MVVM这两个词&#xff0c;就像武林秘籍一样&#xff0c;常常被…

Vue-color:Vue.js 专业颜色选择器组件库 – 支持Vue2/3,TypeScript,暗色主题

简介 Vue-color 是一个专为 Vue.js 设计的颜色选择器组件库&#xff0c;提供了多种风格的颜色选择器组件。它支持 Vue 2.7 和 Vue 3&#xff0c;具有 TypeScript 支持、SSR 兼容性和暗色主题支持。 特性 多种颜色选择器 – 提供 Chrome、Sketch、Photoshop 等多种风格Vue 2.…

ArcGIS定向影像(2)——非传统影像轻量级解决方案

ArcGIS能让用户自己低成本的做出谷歌街景吗&#xff1f;现在ArcGIS Pro 3.2 和 ArcGIS Enterprise 11.2 能够让用户不使用任何插件和扩展的情况下完成街景数据集的构建&#xff0c;数据管理&#xff0c;发布服务和调用的完整解决方案。非常体系化&#xff0c;由底层数据驱动&am…