C++初階學習第七彈——探索STL奧秘(二)——string的模擬實現

標準庫中的string:C++初階學習第六彈——string(1)——標準庫中的string類-CSDN博客

前言:

在前面我們已經學習了如何使用標準庫中的string類,但作為一個合格的程序員,我們不僅要會用,還要知道如何實現string中的類函數等內容,今天我們就來講解一下string的模擬實現

目錄

一、string類的構造

二、string類的拷貝構造

三、string類的析構函數

四、string類的運算符重載

1、operator=的傳統寫法

2、operator=的現代寫法

五、代碼實例

六、總結


string的模擬實現中最重要的就是string類的構造、拷貝構造、賦值運算符重載以及析構函數

接下來我們就圍繞這些重點進行學習

一、string類的構造

首先我們要清楚string類在底層實際上就是一個字符指針和許多類函數,所以它的類成員變量就是:

private:char* _str;

我們先把模擬構造給出來再來講解:

//為了區分標準庫,我們用String
class String
{
public:String(const char* str = ""){if (str == nullptr){assert(false);return;}_str = new char[strlen(str) + 1];strcpy(_str, str);}void String_print(){cout << _str << endl;}
private:char* _str;
};
int main()
{String s1("abc");s1.String_print();return 0;
}

運行結果:

相信一定有細心的朋友已經注意到我們在給參數時并沒有給任何東西,原因如下:

還有一點需要注意的是:我們在賦值時是創建一個新空間來儲存,并不是直接賦值,這就涉及深拷貝的問題了,在下面我們講拷貝構造的時候能更清晰的體現出來

二、string類的拷貝構造

模擬實現的代碼如下:

    String(const String& s): _str(new char[strlen(s._str) + 1]){strcpy(_str, s._str);}

在這里我們主要來講解一下深拷貝和淺拷貝的問題,我們放在一個完整的代碼實例:

class String
{
public:String(const char* str = ""){if (str == nullptr){assert(false);return;}_str = new char[strlen(str) + 1];strcpy(_str, str);}String(const String& s): _str(new char[strlen(s._str) + 1]){strcpy(_str, s._str);}void String_print(){cout << _str << endl;}
private:char* _str;
};
int main()
{String s1("abc");s1.String_print();String s2(s1);s2.String_print();return 0;
}

運行結果:

錯誤示范:

三、string類的析構函數

由于string類對象不管以哪個方式創建時,都需要用new來開辟空間,所以string的析構函數寫法為:

    ~String(){if (_str)     //檢查一下_str是否為空,如果為空就不用再釋放空間了{delete[] _str;_str = nullptr;}}

四、string類的運算符重載

string類的運算符重載整體來說沒啥難度,在這里我們也不做過多講解,重點來講解一下operator=的兩種寫法

1、operator=的傳統寫法

    String& operator=(const String& s){if (s._str != _str){char* ptr = new char[strlen(s._str) + 1];    //+1是因為要多開辟一個空間存放\0strcpy(ptr, s._str);delete _str;                              //清空_str中可能有的數據_str = ptr;}return *this;}

2、operator=的現代寫法

String& operator=(String s)
{swap(_str, s._str);   //swap函數算法庫中存在,所以可以直接使用return *this;
}

單從篇幅上來比較,現代寫法要比傳統寫法精簡的多,那么它們兩個究竟是如何實現它們的功能的呢?我們看下面的分析:

· 傳統寫法:

傳統寫法函數的參數是后值的引用,我們通過創建一個新的字符指針,并開辟空間接受后值,再把這個新創建的指針的地址傳給我們的對象,從而實現了operator=的功能

· 現代寫法:

現代寫法則聰明的使用了算法庫中的swap函數,從而讓函數達到一個很精簡的效果,該函數的參數是后值的臨時拷貝,本來就是深拷貝,所以通過swap交換即可

傳統寫法和現代寫法的過程比較:

五、代碼實例

//為了區分標準庫,我們用String
class String
{
public:String(const char* str = ""){if (str == nullptr){assert(false);return;}_str = new char[strlen(str) + 1];strcpy(_str, str);}String(const String& s): _str(new char[strlen(s._str) + 1]){strcpy(_str, s._str);}//現代寫法String& operator=(String s){swap(_str, s._str);return *this;}傳統寫法//String& operator=(const String& s)//{//    if (s._str != _str)//    {//        char* ptr = new char[strlen(s._str) + 1];    //+1是因為要多開辟一個空間存放\0//        strcpy(ptr, s._str);//        delete _str;                              //清空_str中可能有的數據//        _str = ptr;//    }//    return *this;//}void String_print(){cout << _str << endl;}~String(){if (_str)     //檢查一下_str是否為空,如果為空就不用再釋放空間了{delete[] _str;_str = nullptr;}}
private:char* _str;
};
int main()
{String s1("abc");s1.String_print();String s2(s1);s2.String_print();String s3 = s2;s3.String_print();return 0;
}

運行結果:

六、總結

以上就是string模擬實現的比較重要的部分,其他類函數我們并沒有寫出來,但難度都不大,感興趣的老鐵可以自己摸索一下或者在網上搜一下它的實現

感謝各位大佬觀看,創作不易,還請一鍵三連!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11495.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11495.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11495.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++類和對象下——實現日期類

前言 在學習了類和對象的六大成員函數后&#xff0c;為了鞏固我們學習的知識可以手寫一個日期類來幫助我們理解類和對象&#xff0c;加深對于其的了解。 默認函數 構造函數 既然是寫類和對象&#xff0c;我們首先就要定義一個類&#xff0c;然后根據實際需要來加入類的數據與函…

AI編程工具為什么選github copilot?

Github Copilot 是一個奇跡 它的競爭對手&#xff08;Amazon, Google, Meta, 騰訊&#xff09;都是免費的&#xff0c;但每月10-20美元的Github Copilot市場占有率最高。 1、2021年6月上線&#xff0c;比ChatGPT早近一年半 2、GitHub統計&#xff1a; 88%的用戶獲得效率提升平…

element ui的確認提示框文字樣式修改

修改確認提示框文字樣式修改&#xff0c;使用message屬性修改&#xff1a; 例&#xff1a; js代碼&#xff1a; this.$msgbox({title: 確定要刪除嗎?,message: this.$createElement(p, null, [this.$createElement(span, { style: color: red }, 該素材一旦刪除&#xff0c;…

Spring Boot日志

目錄 一、日志概述 1、為什么要學習日志&#xff1f; 2、日志的用途 &#xff08;1&#xff09;系統監控 &#xff08;2&#xff09;數據采集 &#xff08;3&#xff09;日志審計 二、日志使用 1、打印日志 &#xff08;1&#xff09;在程序中得到日志對象 &#xf…

QNX SLM介紹

QNX SLM SLM是Qnx中用來加載Application的組件&#xff0c;它可以監控Application行為&#xff08;比如異常退出時重新Application拉起&#xff09;、控制Application間的啟動時序。 QNX的SLM與Android RC文件類似。 下面摘自QNX官網介紹 System launch and monitor: launch c…

Redis日常維護流程及技巧:確保穩定性與性能

目錄 一、監控和報警設置 1.實時監控&#xff1a;洞察Redis的脈搏 &#xff08;1&#xff09;. 資源使用監控 &#xff08;2&#xff09;. 數據訪問模式監控 &#xff08;3&#xff09;. 持久化監控 &#xff08;4&#xff09;. 客戶端連接 2.報警機制&#xff1a;快速響…

標準Modbus TCP雙網口開關量模塊

M140E以太網遠程I/O無線數據采集模塊是一款工業級、隔離設計、高可靠性、高穩定性和高精度數據采集模塊&#xff0c;嵌入式32位高性能微處理器MCU&#xff0c;集成2路工業10/100M自適應以太網模塊里面。提供多種I/O&#xff0c;支持標準Modbus TCP&#xff0c;可集成到SCADA、O…

Spring STOMP-連接到消息代理

STOMP 代理中繼維護一個與消息代理的“系統”TCP 連接。這個連接僅用于來自服務器端應用程序的消息&#xff0c;不用于接收消息。您可以為此連接配置STOMP憑據&#xff08;即STOMP幀的login和passcode頭部&#xff09;。這在XML命名空間和Java配置中都以systemLogin和systemPas…

CentOs搭建Kubernetes集群

kubeadm minikube 還是太“迷你”了&#xff0c;方便的同時也隱藏了很多細節&#xff0c;離真正生產環境里的計算集群有一些差距&#xff0c;畢竟許多需求、任務只有在多節點的大集群里才能夠遇到&#xff0c;相比起來&#xff0c;minikube 真的只能算是一個“玩具”。 Kuber…

spring基礎使用(案例)

基于xml使用&#xff1a; 準備&#xff1a; 1.Dao層&#xff08;接口&#xff09;&#xff1a; public interface UserDao {public void save(); } 1.1 Dao層&#xff08;實現類&#xff09;&#xff1a; public class UserDaoIim implements UserDao {Overridepublic vo…

Day53代碼隨想錄動態規劃part13:300.最長遞增子序列、674. 最長連續遞增序列、718. 最長重復子數組

Day52 動態規劃part13 300.最長遞增子序列 leetcode鏈接&#xff1a;300. 最長遞增子序列 - 力扣&#xff08;LeetCode&#xff09; 題意&#xff1a;給你一個整數數組 nums &#xff0c;找到其中最長嚴格遞增子序列的長度。子序列是由數組派生而來的序列&#xff0c;刪除&a…

23種設計模式(軟考中級 軟件設計師)

設計模式 23個設計模式&#xff0c;23個意圖 1. 設計模式概要 設計模式的核心在于提供了相關問題的解決方案&#xff0c;使得人們可以更加簡單方便的復用成功的設計和體系結構 設計模式的類別 創建型結構型行為型類工廠方法模式適配器模式&#xff08;類&#xff09;解釋器模…

物聯網五層架構分析

物聯網五層架構分析 隨著科技的迅速發展&#xff0c;物聯網&#xff08;IoT&#xff09;作為日常生活中不可或缺的一部分&#xff0c;已融入人們的生活和工作中。物聯網五層架構&#xff0c;包括感知層、網絡層、數據層、應用層和業務層&#xff0c;扮演著關鍵的角色。 感知層 …

網絡庫-libcurl介紹

1.簡介 libcurl 是一個功能強大的庫&#xff0c;支持多種協議&#xff0c;用于數據傳輸。它廣泛應用于實現網絡操作&#xff0c;如HTTP、HTTPS、FTP、FTPS、SCP、SFTP等。libcurl 提供了豐富的 API&#xff0c;可以在多種編程語言中使用。 libcurl 主要特點 支持多種協議&am…

FreeRTOS計數型信號量

目錄 一、計數型信號量簡介 二、計數型信號量相關API 1、創建計數型信號量 2、釋放計數型信號量 3、獲取計數型信號量 4、獲取計數型信號量的計數值 三、計數型信號量實操 1、實驗需求 2、CubeMX配置 3、代碼實現 一、計數型信號量簡介 ①取值只有0與1兩種狀態的信號…

基于Springboot的滴答拍攝影

基于SpringbootVue的滴答拍攝影設計與實現 開發語言&#xff1a;Java數據庫&#xff1a;MySQL技術&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系統展示 用戶登錄 首頁 攝影作品 攝影服務 攝影論壇 后臺登錄 后臺首頁 用戶管理 攝影師管理 攝影作…

YOLOv8小白中的小白安裝環境教程!沒一個字廢話,看一遍不踩坑!

文章目錄 去哪里下代碼&#xff1f;怎么下代碼&#xff1f;怎么裝環境&#xff1f;命令行界面(CLI)指令和Python腳本區別&#xff1f;附錄1 conda常用指令附錄2 git常用指令附錄3 項目代碼文件作用 去哪里下代碼&#xff1f; 下載代碼請大家直接去 YOLOv8的官方倉庫下載&#…

HTTP和HTTPS的區別和聯系

目錄 1. 簡介2. TLS 握手過程3. 常見的加密算法3.1 對稱加密算法3.2 非對稱加密算法 1. 簡介 HTTPS在HTTP的基礎上引入了一個TLS層&#xff0c;采用密文進行傳輸&#xff0c;結合對稱加密技術和非對稱加密技術來實現數據的安全性和完整性。 客戶端會生成隨機密鑰&#xff0c;…

讓 計算機 將 數學 公式 表達式 的計算過程繪制出來 【mathematical-expression(MAE)】

目錄 文章目錄 目錄介紹開始實戰引入數學表達式計算庫引入流程圖代碼生成庫開始進行生成 介紹 大家好 今天我們來分享一個新知識&#xff0c;將數學表達式的整個計算過程&#xff0c;以及計算繁多結果在 Java 中繪制出來&#xff0c;計算機中的數學表達式計算的功能很常見了&a…