C++中String類的實現

https://www.cnblogs.com/zhizhan/p/4876093.html

原文:http://noalgo.info/382.html

String是C++中的重要類型,程序員在C++面試中經常會遇到關于String的細節問題,甚至要求當場實現這個類。只是由于時間關系,可能只要求實現構造函數、析構函數、拷貝構造函數等關鍵部分。
String的實現涉及很多C++的基礎知識、內存控制及異常處理等問題,仔細研究起來非常復雜,本文主要做一個簡單的總結和歸納。

?

一 整體框架

面試時由于時間關系,面試官一般不會要求很詳盡的String的功能,一般是要求實現構造函數、拷貝構造函數、賦值函數、析構函數這幾個非常重要的部分。因為String里涉及動態內存的管理,默認的拷貝構造函數在運行時只會進行淺復制,即只復制內存區域的指針,會造成兩個對象指向同一塊內存區域的現象。如果一個對象銷毀或改變了該內存區域,會造成另一個對象運行或者邏輯上出錯。這時就要求程序員自己實現這些函數進行深復制,即不止復制指針,需要連同內存的內容一起復制。

除了以上四個必須的函數,這里還實現了一些附加的內容。

  • 若干個運算符重載,這里的幾個是常見的運算符,可以加深對String的認識和運算符重載的理解。
  • 兩個常用的函數,包括取字符串長度和取C類型的字符串。
  • 兩個處理輸入輸出的運算符重載,為了使用的方便,這里把這兩個運算符定義為友元函數。

整體的類的框架如下所示。

class String
{
public:String(const char *str = NULL);	//通用構造函數String(const String &str);		//拷貝構造函數~String();						//析構函數String operator+(const String &str) const;	//重載+String& operator=(const String &str);		//重載=String& operator+=(const String &str);		//重載+=bool operator==(const String &str) const;	//重載==char& operator[](int n) const;				//重載[]size_t size() const;		//獲取長度const char* c_str() const;	//獲取C字符串friend istream& operator>>(istream &is, String &str);//輸入friend ostream& operator<<(ostream &os, String &str);//輸出private:char *data;		//字符串size_t length;	//長度
};

注意,類的成員函數中,有一些是加了const修飾的,表示這個函數不會對類的成員進行任何修改。一些函數的輸入參數也加了const修飾,表示該函數不會對改變這個參數的值。

二 具體實現

下面逐個進行成員函數的實現。

同樣構造函數適用一個字符串數組進行String的初始化,默認的字符串數組為空。這里的函數定義中不需要再定義參數的默認值,因為在類中已經聲明過了。

另外,適用C函數strlen的時候需要注意字符串參數是否為空,對空指針調用strlen會引發內存錯誤。

 String::String(const char *str)//通用構造函數
{if (!str){length = 0;data = new char[1];*data = '\0';}else{length = strlen(str);data = new char[length + 1];strcpy(data, str);}
}

拷貝構造函數需要進行深復制。

String::String(const String &str)//拷貝構造函數
{length = str.size();data = new char[length + 1];strcpy(data, str.c_str());
}

析構函數需要進行內存的釋放及長度的歸零。

String::~String()//析構函數
{delete []data;length = 0;
}

重載字符串連接運算,這個運算會返回一個新的字符串。

String String::operator+(const String &str) const//重載+
{String newString;newString.length = length + str.size();newString.data = new char[newString.length + 1];strcpy(newString.data, data);strcat(newString.data, str.data);return newString;
}

重載字符串賦值運算,這個運算會改變原有字符串的值,為了避免內存泄露,這里釋放了原先申請的內存再重新申請一塊適當大小的內存存放新的字符串。

String& String::operator=(const String &str)//重載=
{if (this == &str)	return *this;delete []data;length = str.length;data = new char[length + 1];strcpy(data, str.c_str());return *this;
}

重載字符串+=操作,總體上是以上兩個操作的結合。

String& String::operator+=(const String &str)//重載+=
{length += str.length;char *newData = new char[length + 1];strcpy(newData, data);strcat(newData, str.data);delete []data;data = newData;return *this;
}

重載相等關系運算,這里定義為內聯函數加快運行速度。

inline bool String::operator==(const String &str) const//重載==
{if (length != str.length)	return false;return strcmp(data, str.data) ? false : true;
}

重載字符串索引運算符,進行了一個簡單的錯誤處理,當長度太大時自動讀取最后一個字符。

inline char& String::operator[](int n) const//重載[]
{if (n >= length) return data[length-1]; //錯誤處理else return data[n];
}

重載兩個讀取私有成員的函數,分別讀取長度和C字符串。

inline size_t String::size() const//獲取長度
{return length;
}

重載輸入運算符,先申請一塊足夠大的內存用來存放輸入字符串,再進行新字符串的生成。這是一個比較簡單樸素的實現,網上很多直接is>>str.data的方法是錯誤的,因為不能確定str.data的大小和即將輸入的字符串的大小關系。

istream& operator>>(istream &is, String &str)//輸入
{char tem[1000];  //簡單的申請一塊內存is >> tem;str.length = strlen(tem);str.data = new char[str.length + 1];strcpy(str.data, tem);return is;
}

重載輸出運算符,只需簡單地輸出字符串的內容即可。注意為了實現形如cout<<a<<b的連續輸出,這里需要返回輸出流。上面的輸入也是類似。

ostream& operator<<(ostream &os, String &str)//輸出
{os << str.data;return os;
}
inline const char* String::c_str() const//獲取C字符串
{return data;
}

三 功能測試

編碼完成后需要對代碼進行測試,以下是一個簡單但不夠嚴謹的測試。

int main()
{String s;	cin >> s;	cout << s << ": " << s.size() << endl;char a[] = "Hello", b[] = "World!";String s1(a), s2(b);	cout << s1 << " + " << s2 << " = " << s1 + s2 << endl;String s3 = s1 + s2;if (s1 == s3)	cout << "First: s1 == s3" << endl;s1 += s2;if (s1 == s3)	cout << "Second: s1 == s3" << endl;/*程序輸入輸出為:123456789123456789: 9Hello + World! = HelloWorld!Second: s1 == s3Press any key to continue . . .*/
}

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

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

相關文章

Ubuntu軟件更新失敗

剛安裝好Ubuntu以后需要將系統的軟件都更新一下&#xff0c;但是遇到一個問題就是下載倉庫信息失敗&#xff0c;大概是這個樣子的錯誤&#xff1a; 經國遇到這樣的問題可以試一下下面這個命令&#xff1a; sudo rm -rf /var/lib/apt/lists/* sudo apt-get update參考網址&…

getsockname函數與getpeername函數的使用

https://www.tuicool.com/articles/V3Aveygetsockname和getpeername函數 getsockname函數用于獲取與某個套接字關聯的本地協議地址 getpeername函數用于獲取與某個套接字關聯的外地協議地址 定義如下&#xff1a;[cpp] view plaincopy#include<sys/socket.h> int gets…

Ubuntu根目錄空間不足

自己在固態硬盤上安裝的Ubuntu&#xff0c;結果只用了一天就顯示磁盤空間不足。查看空間以后發現Ubuntu自己安裝的時候默認給根目錄分配的是10GB,然而我們下載的軟件以及環境等一般都安裝在根目錄空間下&#xff0c;尤其是/usr目錄所占的空間很大。 不得已我在網上查找了如何給…

Linux命令【一】基本命令

shell命令和bash命令相同&#xff0c;指的是命令解析器 快捷鍵 history 所有的歷史命令ctrl P 向上滾動命令 ctrl N 向下滾動命令 ctrlB將光標向前移動 ctrlF將光標向后移動 ctrlA移動到命令行頭部 ctrlE移動到命令行尾部 光標刪除操作&#xff1a;刪除光標前面字符ctrlh或…

The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

http://www.jb51.net/article/119654.htmThe MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 意思貌似MYSQL還運行在 --skip-grant-tables模式&#xff0c;如何讓他回到原來的模式 第一種方法&#xff1a;原來在mysql.ini文…

解決Ubuntu“下載額外數據文件失敗 ttf-mscorefonts-installer”的問題

參考博客&#xff1a;傳送門 下載[ttf-mscorefonts-installer.zip](https://pan.baidu.com/s/1i5rLfMH) 密碼: h76g 然后解壓到下載的目錄&#xff0c;在當前目錄執行命令&#xff1a; sudo dpkg-reconfigure ttf-mscorefonts-installer這條命令手動指定文件夾的位置,重新配置…

【C語言】單鏈表的相關熱點面試題(包括:從尾到頭打印,逆置,冒泡,尋找中間節點,倒數k節點)

https://blog.csdn.net/hanjing_1995/article/details/51539599從尾到頭打印單鏈表[cpp] view plaincopyvoid FromTailToHeadPrint(SListNode*& head) { stack<SListNode*> s; SListNode* cur head; while (cur) { s.push(cur); …

Linux命令【二】終端+Vim

需要先安裝net-tools ifconfig eth0 網卡&#xff0c;硬件地址為MAC 地址&#xff0c;網卡編號&#xff0c;絕對不會重復 lo 回環地址 測試兩臺主機之間能否通信&#xff1a;ping IP或域名 [-c 4//回饋四條信息 -i//每隔多少秒回饋一次] 得到域名對應的IPnslookup 域名得到域…

Linux如何將文件中內容放到粘貼板上

沒有找到如何在vim中將內容復制到粘貼板上&#xff0c;只找到了使用另一個軟件進行操作。 首先安裝xsel sudo apt-get install xsel # 將剪切板中的內容輸出到文件 echo $(xsel --clipboard) >> a.txt# 將文件的內容復制到剪切板 cat a.txt | xsel --clipboard

【C語言】str類與men庫函數的實現(如:strcpy,strcmp,strstr,strcat,memmove,memcpy)

https://blog.csdn.net/hanjing_1995/article/details/51539583strcpy拷貝源字符串到子字符串&#xff0c;包括‘\0’。代碼實現&#xff1a;[cpp] view plaincopychar* strcpy(char* dst,const char* src) { assert(src); char* ret dst; while (*src) …

【筆試常考】C語言:深度剖析strlen,sizeof

https://blog.csdn.net/hanjing_1995/article/details/51539532在之前的博客中&#xff0c;我也探索過strlen,sizeof區別&#xff0c;詳情可見博客http://10740184.blog.51cto.com/10730184/1705820。關于strlen,sizeof均可求字符串長度&#xff0c;這兩者是筆試面試常考的知識…

vim環境配置 +vimplus配置

vim配置 參考網站&#xff1a;傳送門 這個網站詳細說明了vim配置的命令&#xff0c;我挑選了我想要用的部分&#xff0c;自己配置了一下。 配置vim的文件有兩個&#xff0c;一個是/etc/vim/vimrc 這個是系統配置文件&#xff0c;修改這個文件將會修改所有用戶的vim環境&…

劍指offer面試題:替換空格

https://blog.csdn.net/yanxiaolx/article/details/52235212題目&#xff1a;請實現一個函數&#xff0c;把字符串中的每個空格替換成“%20”。例如輸入“We are happy.”&#xff0c;則輸出“We%20are%20happy.”。解析&#xff1a;時間復雜度為O(n)的解法。完整代碼及測試用例…

數據庫原理及應用【一】引言

什么是數據庫&#xff1a;一個大規模的集成的數據集合 作用&#xff1a;描述現實世界的實體(entities)以及實體之間的關系 管理數據庫的系統軟件&#xff1a;DBMS 文件是一個平滑的字符流&#xff0c;無法完成信息的檢索和管理 數據&#xff08;data&#xff09;:用來描述現…

Linux命令【三】gcc編譯+靜態庫+動態庫+makefile+gdb調試

用C編譯器編譯源文件&#xff1a;gcc 源文件 -o 可執行文件名 詳細步驟&#xff1a; gcc -E a.c -o a.i預處理器將頭文件展開&#xff0c;宏替換&#xff0c;去掉注釋gcc -S a.i -o a.s編譯器將C文件變成匯編文件gcc -c a.s -o a.o匯編器將會變文件變成二進制文件gcc a.o -o a…

用c++模擬實現一個學生成績管理系統

https://blog.csdn.net/yanxiaolx/article/details/53393437題目&#xff1a;用c模擬實現一個學生成績的信息管理系統&#xff0c;要求能添加、刪除、修改、查看和保存學生的信息等功能 源代碼如下:[cpp] view plaincopy#define _CRT_SECURE_NO_WARNINGS #include<iostr…

Linux命令【四】文件+虛擬內存+常用系統函數

File*其實是一個結構體 文件描述符FD&#xff1a;索引到對應的磁盤文件文件讀寫位置指針FP_POS&#xff0c;如果同時讀寫需要注意文件指針的位置I/O緩沖區BUFFER&#xff1a;保存內存指針&#xff0c;默認大小是8kb&#xff0c;用于減小我們對硬盤操作的次數。因為我們對硬盤的…

Python3列表

操作&#xff1a;索引、切片、加、乘、檢查成員、確定序列長度、確定最大最小元素 定義&#xff1a; 列表名 [元素]下標列表名[x] 截取:列表名[x:y] 更新&#xff1a; list[x]y 或者使用append()方法添加列表項刪除&#xff1a; del list[x]常用操作&#xff1a; 截取與…

Linux驚群效應詳解(最詳細的了吧)

https://blog.csdn.net/lyztyycode/article/details/78648798?locationNum6&fps1 linux驚群效應詳細的介紹什么是驚群&#xff0c;驚群在線程和進程中的具體表現&#xff0c;驚群的系統消耗和驚群的處理方法。1、驚群效應是什么&#xff1f;驚群效應也有人叫做雷鳴群體效應…

epoll原理詳解(最清晰)

https://blog.csdn.net/lyztyycode/article/details/79491419我只是把內容搬運過來做個記錄&#xff0c;方便自己以后回頭看。第一部分&#xff1a;select和epoll的任務關鍵詞&#xff1a;應用程序 文件句柄 用戶態 內核態 監控者要比較epoll相比較select高效在什么地方&#x…