C++:string模擬實現中的賦值拷貝函數現代寫法詭異地崩掉了......

事情是這樣的:

博主今天回看以前實現過的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…