C++之string的模擬實現

string

  • 手寫C++字符串類
      • 類的基本結構與成員變量
      • 一、構造函數與析構函數
      • 二、賦值運算符重載
      • 三、迭代器支持
      • 四、內存管理與擴容機制
      • 五、字符串操作函數
      • 六、運算符重載
      • 總結

在這里插入圖片描述

手寫C++字符串類

從零實現一個簡易版std::string

類的基本結構與成員變量

namespace zzh {
class string {
private:char* _str;        // 存儲字符串的字符數組size_t _size;      // 當前字符串長度size_t _capacity;  // 已分配的容量
public:static const size_t npos;  // 表示"不存在的位置"// 各類成員函數...
};
}

這個自定義字符串類主要通過動態分配的字符數組_str來存儲字符串內容,并維護兩個重要狀態:_size表示當前字符串長度,_capacity表示已分配的內存容量。

  1. 基本成員變量
    在自定義 string 類中,我們需要定義一些基本的成員變量來存儲字符串的內容和相關信息:
    _str:用于存儲字符串的字符數組,通常是一個動態分配的 char 類型數組。
    _size:表示當前字符串的實際長度,不包括結尾的空字符 \0。
    _capacity:表示分配的內存容量,通常大于或等于 _size,用于優化內存分配效率。
  2. 構造函數和析構函數
    構造函數用于初始化 string 對象,常見的構造方式包括:
    從 C 風格字符串構造(const char*):通過 strlen 計算字符串長度,并動態分配內存來存儲字符串內容。
    拷貝構造函數:用于從另一個 string 對象構造新對象,需要深拷貝內存以避免懸掛指針問題。
    默認構造函數:用于創建一個空字符串。
    析構函數則負責釋放動態分配的內存,避免內存泄漏。
  3. 賦值運算符重載
    為了支持對象之間的賦值操作,我們需要重載賦值運算符 =。在實現時,需要注意自賦值的情況,并進行深拷貝以確保兩個對象的內存獨立。
  4. 內存管理
    字符串操作中,內存管理是一個關鍵問題。我們需要在字符串長度超過當前容量時動態擴展內存。通常的做法是將容量加倍,以減少頻繁的內存分配操作。
  5. 迭代器支持
    為了方便遍歷字符串中的字符,我們可以提供迭代器支持。通過定義 begin() 和 end() 方法,返回指向字符串首尾的指針,可以方便地使用標準庫算法。
  6. 常見操作實現
    追加字符或字符串:通過 push_back 和 append 方法,可以在字符串末尾添加字符或另一個字符串的內容。在實現時,需要注意內存容量是否足夠,并在必要時進行擴展。
    查找和替換:提供 find 方法用于查找字符或子字符串的位置,insert 和 erase 方法用于插入和刪除字符或子字符串。
    比較操作:重載比較運算符(如 <、>、== 等),以便可以直接比較兩個 string 對象的大小。

一、構造函數與析構函數

// 1. 從C風格字符串構造
string::string(const char* str)
{_size = strlen(str);_str = new char[_size + 1];_capacity = _size;memcpy(_str, str, _size + 1);
}// 2. 拷貝構造函數
string::string(const string& s)
{_size = s._size;_capacity = s._capacity;_str = new char[_capacity + 1];memcpy(_str, s._str, _size + 1);
}// 3. 析構函數
string::~string()
{delete[] _str;_str = nullptr;_size = 0;_capacity = 0;
}

關鍵點

  • 構造函數負責分配內存并復制字符串內容
  • 拷貝構造函數實現深拷貝,避免內存共享
  • 析構函數必須釋放動態分配的內存,防止內存泄漏

二、賦值運算符重載

string& string::operator=(const string& s)
{if (this != &s){char* tmp = new char[s._capacity + 1];memcpy(tmp, s._str, s._size + 1);delete[] _str;  // 注意:原代碼此處順序有誤,已修正_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;
}

技術要點

  • 使用臨時變量確保異常安全
  • 自我賦值檢查避免無效操作
  • 先分配新內存再釋放舊內存,防止內存泄漏

三、迭代器支持

string::iterator string::begin() { return _str; }
string::iterator string::end() { return _str + _size; }

說明

  • 迭代器本質是字符指針
  • begin()返回字符串首地址
  • end()返回字符串末尾的下一個位置

四、內存管理與擴容機制

// 預分配內存
void string::reserve(size_t n)
{if (n > _capacity){char* tmp = new char[n + 1];memcpy(tmp, _str, _size + 1);delete[] _str;_str = tmp;_capacity = n;}
}// 追加字符
void string::push_back(char c)
{if (_size >= _capacity){size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;reserve(newcapacity);}_str[_size++] = c;  // 注意:原代碼此處錯誤地寫入了固定字符'c'_str[_size] = '\0';
}

內存管理策略

  • 采用指數級擴容(2倍)減少內存分配次數
  • reserve()實現預分配,避免頻繁擴容
  • 每次擴容后保留額外空間,提高插入效率

五、字符串操作函數

// 追加C風格字符串
void string::append(const char* str)
{size_t len = strlen(str);if (_size + len > _capacity){size_t newcapacity = 2 * _capacity > _size + len ? 2 * _capacity : _size + len;reserve(newcapacity);}memcpy(_str + _size, str, len);  // 注意:原代碼此處多復制了一個終止符_size += len;_str[_size] = '\0';  // 手動添加終止符
}// 查找字符
size_t string::find(char c, size_t pos = 0) const
{for (size_t i = pos; i < _size; i++){if (_str[i] == c)return i;}return npos;
}// 插入字符
string& string::insert(size_t pos, char c)
{assert(pos <= _size);if (_size >= _capacity){size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;reserve(newcapacity);}// 從后向前移動元素for (size_t i = _size; i > pos; i--)_str[i] = _str[i - 1];_str[pos] = c;_size++;return *this;
}

核心算法

  • append()通過內存拷貝實現高效追加
  • find()線性查找目標字符
  • insert()通過元素后移實現插入操作
  • 使用memmove()處理內存重疊情況

六、運算符重載

// 比較運算符
bool string::operator<(const string& s)
{size_t i1 = 0, i2 = 0;while (i1 < _size && i2 < s._size){if (_str[i1] < s._str[i2])return true;else if (_str[i1] > s._str[i2])return false;i1++; i2++;}return i1 < s._size;  // 注意:原代碼此處邏輯有誤,已修正
}// 索引運算符
char& string::operator[](size_t index)
{assert(index < _size);return _str[index];
}

實現要點

  • 比較運算符按字典序逐字符比較
  • 索引運算符提供隨機訪問能力
  • 提供常量和非常量兩個版本的重載

總結

通過手寫這個簡易版string類,我們深入理解了標準庫字符串類的核心機制:動態內存管理、深拷貝實現、迭代器設計、擴容策略等。雖然現代C++編程中應優先使用std::string,但掌握這些底層原理有助于寫出更高效、更安全的代碼。

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

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

相關文章

修改Docker鏡像源

配置文件位置&#xff1a; sudo vim /etc/docker/daemon.json Docker 或 containerd 的鏡像加速器配置&#xff0c;旨在提高從 Docker Hub 拉取鏡像的速度。 { "features": { "buildkit": true, "containerd-snapshotter": true }, …

服務器帶寬線路的區別(GIA、CN2、BGP、CMI等)

服務器帶寬線路的區別&#xff08;GIA、CN2、BGP、CMI等&#xff09; 一、BGP線路 1. 定義與技術特點 BGP&#xff08;Border Gateway Protocol&#xff0c;邊界網關協議&#xff09;是一種用于不同自治系統&#xff08;AS&#xff09;之間交換路由信息的協議&#xff0c;屬…

從0到1搭建AI繪畫模型:Stable Diffusion微調全流程避坑指南

從0到1搭建AI繪畫模型&#xff1a;Stable Diffusion微調全流程避坑指南 系統化學習人工智能網站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目錄 從0到1搭建AI繪畫模型&#xff1a;Stable Diffusion微調全流程避坑指南摘要引言一、數據集構…

VSCode + GD32F407 構建燒錄

前言 最近調試一塊 GD32F407VET6&#xff08;168Mhz&#xff0c;8Mhz晶振&#xff09; 板子時&#xff0c;踩了一些“啟動失敗”的坑。本以為是時鐘配置有誤&#xff0c;最后發現是鏈接腳本&#xff08;.ld 文件&#xff09;沒有配置好&#xff0c;導致程序根本沒能正常執行 ma…

AI繪畫提示詞:從零開始掌握Prompt Engineering的藝術

文章目錄 什么是AI繪畫提示詞&#xff1f;提示詞的基本結構主體描述場景/背景風格指定技術參數負面提示人物肖像模板風景模板 高級技巧權重調整混合風格顏色控制情緒氛圍 常見問題與解決方法手部變形問題構圖不理想風格不夠突出 提示詞示例庫科幻場景奇幻人物靜物畫 結語 在當今…

在 Linux 上安裝 Minikube:輕松搭建本地 Kubernetes 單節點集群

&#x1f525;「炎碼工坊」技術彈藥已裝填&#xff01; 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 一、Minikube 是什么&#xff1f; Minikube 是 Kubernetes 官方推出的輕量級工具&#xff0c;專為開發者設計&#xff0c;用于在本地快速搭建單節點 Kube…

day41 python圖像識別任務

目錄 一、數據預處理&#xff1a;為模型打下堅實基礎 二、模型構建&#xff1a;多層感知機的實現 三、訓練過程&#xff1a;迭代優化與性能評估 四、測試結果&#xff1a;模型性能的最終檢驗 五、總結與展望 在深度學習的旅程中&#xff0c;多層感知機&#xff08;MLP&…

JS數組 concat() 與擴展運算符的深度解析與最佳實踐

文章目錄 前言一、語法對比1. Array.prototype.concat()2. 擴展運算符&#xff08;解構賦值&#xff09; 二、性能差異&#xff08;大規模數組&#xff09;關鍵差異原因 三、適用場景建議總結 前言 最近工作中遇到了一個大規模數組合并相關的問題&#xff0c;在數據合并時有些…

一套qt c++的串口通信

實現了創建線程使用串口的功能 具備功能: 1.線程使用串口 2.定時發送隊列內容&#xff0c;防止粘包 3.沒處理接收粘包&#xff0c;根據你的需求來&#xff0c;handleReadyRead函數中&#xff0c;可以通過m_receiveBuffer來緩存接收&#xff0c;然后拆分數據來處理 源碼 seri…

設計模式-發布訂閱

文章目錄 發布訂閱概念發布訂閱 vs 監聽者例子代碼 發布訂閱概念 發布/訂閱者模式最大的特點就是實現了松耦合&#xff0c;也就是說你可以讓發布者發布消息、訂閱者接受消息&#xff0c;而不是尋找一種方式把兩個分離 的系統連接在一起。當然這種松耦合也是發布/訂閱者模式最大…

windows-cmd 如何查詢cpu、內存、磁盤的使用情況

在 Windows 中&#xff0c;您可以使用命令提示符&#xff08;CMD&#xff09;通過一些命令來查詢 CPU、內存和磁盤的使用情況。以下是常用的命令和方法&#xff1a; 1. 查詢 CPU 使用情況 使用 wmic 命令 wmic cpu get loadpercentage 這個命令會顯示當前 CPU 的使用百分比…

allWebPlugin中間件VLC專用版之截圖功能介紹

背景 VLC控件原有接口具有視頻截圖方法&#xff0c;即video對象的takeSnapshot方法&#xff0c;但是該方法返回的是一個IPicture對象&#xff0c;不適合在谷歌等現代瀏覽器上使用。因此&#xff0c;本人增加一個新的視頻截圖方法takeSnapshot2B64方法&#xff0c;直接將視頻截圖…

第Y5周:yolo.py文件解讀

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 本次任務&#xff1a;將YOLOv5s網絡模型中的C3模塊按照下圖方式修改形成C2模塊&#xff0c;并將C2模塊插入第2層與第3層之間&#xff0c;且跑通YOLOv5s。 任務…

寶塔安裝ssh證書報錯:/usr/bin/curl: symbol lookup error: curl_easy_header

原因&#xff1a; 你當前的 curl 命令版本是 7.70.0&#xff08;不是系統默認版本&#xff0c;應該是你手動安裝的&#xff09;。它鏈接的是 /usr/local/lib/libcurl.so.4&#xff0c;而不是 CentOS 系統默認的 /usr/lib64/libcurl.so.4。/usr/local/lib/libcurl.so.4 很可能是…

Apache SeaTunnel 引擎深度解析:原理、技術與高效實踐

Apache SeaTunnel 作為新一代高性能分布式數據集成平臺&#xff0c;其核心引擎設計融合了現代大數據處理架構的精髓。 Apache SeaTunnel引擎通過分布式架構革新、精細化資源控制及企業級可靠性設計&#xff0c;顯著提升了數據集成管道的執行效率與運維體驗。其模塊化設計允許用…

測試用例及黑盒測試方法

一、測試用例 1.1 基本要素 測試用例&#xff08;Test Case&#xff09;是為了實施測試而向被測試的系統提供的一組集合&#xff0c;這組集合包含&#xff1a;測試環境、操作步驟、測試數據、預期結果等4個主要要素。 1.1.1 測試環境 定義&#xff1a;測試執行所需的軟硬件…

硬件工程師筆記——運算放大電路Multisim電路仿真實驗匯總

目錄 1 運算放大電路基礎 1.1 概述 1.1.1 基本結構 1.1.2 理想特性 1.2 運算放大分析方法 1.2.1 虛短 1.2.2虛斷 1.2.3 疊加定理 2 同向比例運算放大電路 2.1 概述 2.1.1 基本電路結構 2.1.2 電路原理 2.2 仿真分析 2.2.1 電壓增益 2.2.2 相位分析 3 反向比例運…

板凳-------Mysql cookbook學習 (九)

第4章&#xff1a;表管理 4.0 引言 MySQL &#xff1a;&#xff1a; 員工樣例數據庫 &#xff1a;&#xff1a; 3 安裝 https://dev.mysql.com/doc/employee/en/employees-installation.html Employees 數據庫與幾種不同的 存儲引擎&#xff0c;默認情況下啟用 InnoDB 引擎。編…

MySQL省市區數據表

數據結構簡單展示一下 具體的可以點擊文章最后的鏈接地址下載 連接地址中有兩個文件一個是詳細的另一個是簡潔的 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for ln_new_region -- ---------------------------- DROP…

無人機報警器探測模塊技術解析!

一、運行方式 1. 頻譜監測與信號識別 全頻段掃描&#xff1a;模塊實時掃描900MHz、1.5GHz、2.4GHz、5.8GHz等無人機常用頻段&#xff0c;覆蓋遙控、圖傳及GPS導航信號。 多路分集技術&#xff1a;采用多傳感器陣列&#xff0c;通過信號加權合并提升信噪比&#xff0c;…