亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++字符串類的封裝你真的了解嗎

 更新時間:2022年02月14日 15:00:48   作者:是小明同學啊  
這篇文章主要為大家詳細介紹了C++字符串類的封裝,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

字符串類的封裝

常規(guī)代碼

頭文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class MyString//字符串應該是維護著一個字符數(shù)組的,在堆區(qū)
{
public:
	MyString(const char* str);//有參構(gòu)造函數(shù)
	MyString(const MyString& str);//拷貝構(gòu)造函數(shù)
	~MyString();//析構(gòu)函數(shù)(是需要的,因為這個類中還維護著一個指針,需要自己釋放)
private:
	char* pString;//維護在堆區(qū)開辟的字符數(shù)組
	int m_Size;//字符串長度(不統(tǒng)計\0)
};

在頭文件中定義了MyString類中應該有的屬性和三個函數(shù)。(有參構(gòu)造函數(shù)接收字符串并創(chuàng)建對象)(拷貝構(gòu)造函數(shù)可以接收同類型的對象并且復制出一個新的對象)(析構(gòu)函數(shù)負責在釋放掉本對象的同時釋放掉對象中維護的指針)

函數(shù)實現(xiàn)文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"myString.h";
//MyString str = "123";
MyString::MyString(const char* str)//有參構(gòu)造函數(shù),傳進去的參數(shù)是一個字符串,返回的是MyString類型的對象。
{
	cout<<"MyString的有參構(gòu)造函數(shù)調(diào)用"<<endl;
	this->pString = new char[strlen(str) + 1];//給本對象的pString準備空間。
	strcpy(this->pString, str);//將傳進來帶的字符串的地址也傳給本對象的pString處,str是字符串,不能調(diào)用pString屬性。
	this->m_Size = strlen(str);
}
MyString::MyString(const MyString& str)//拷貝構(gòu)造函數(shù)
{
	//這個需要深拷貝,因為類中有個指針。注意:深拷貝是對指針進行的深拷貝,也就是會傳進來個對象,然后給這個對象中的指針 分配傳進來的對象中的指針的大小的空間,然后將這個值也賦值到本指針中。
	cout << "MyString的拷貝函數(shù)調(diào)用" << endl;
	this->pString = new char[strlen(str.pString)+1];
	strcpy(this->pString , str.pString);
	this->m_Size = str.m_Size;
}
MyString::~MyString()//析構(gòu)(是需要的,因為這個類中還維護著一個指針,需要自己釋放)
{
	cout << "MyString的析構(gòu)函數(shù)調(diào)用" << endl;
	if (this->pString != NULL)
	{
		delete[] this->pString;
		this->pString = NULL;
	}
}

拷貝構(gòu)造和有參構(gòu)造的區(qū)別就是:

1,有參構(gòu)造傳進去的是一個字符串,返回成一個對象。所以要的是對象的各個屬性與字符串的屬性的匹配。

2,拷貝構(gòu)造傳進去的是一個對象,返回的也是一個對象,所以要的是傳進來的對象和本對象(要創(chuàng)建的對象)之間屬性的對應。

3,如果拷貝構(gòu)造的時候發(fā)現(xiàn)需要拷貝個指針,那么就不能直接使用編譯器的拷貝構(gòu)造函數(shù)了,因為編譯器的拷貝構(gòu)造函數(shù)構(gòu)造出來的對象的指針是和傳進來的對象的指針是指向同一塊地方的,那么等到需要釋放指針的時候就會出現(xiàn)重釋放的錯誤。**(這也是為什么需要自己重新創(chuàng)建拷貝構(gòu)造的原因)**如果類中不需要維護指針,那么就不需要自己寫拷貝構(gòu)造(自己為指針再創(chuàng)建空間)。

Test文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include "myString.h";

int main()
{
	MyString str = "abc";//調(diào)用默認構(gòu)造
	//和后面的一樣MyString str("abc");
	MyString str2 = str;//調(diào)用拷貝構(gòu)造
	return 0;
}

注意,這里的“abc”就是傳進來的字符串str,然后這里的str就是創(chuàng)建出來的MyString類型的對象。

運行的結(jié)果:

MyString的有參構(gòu)造函數(shù)調(diào)用
MyString的拷貝函數(shù)調(diào)用
MyString的析構(gòu)函數(shù)調(diào)用
MyString的析構(gòu)函數(shù)調(diào)用

重載左移>>

如果想進行

cout<<str<<endl;代碼肯定會報錯,因為str是MyString類型的對象,<<不認識這個。

所以,這個時候就需要重載一下<<左移運算符,可以在函數(shù)文件中實現(xiàn)。(需要用全局函數(shù)配合友元進行重載)

實現(xiàn)函數(shù):

ostream& operator<<(ostream& cout, MyString& str) //重載左移運算符
{
	cout << str.pString;//這里的pString是類中的私有屬性,所以需要在原類(在頭文件中)中給整個重載函數(shù)設置友元
	return cout;
}

頭文件

class MyString
{
	friend ostream& operator<<(ostream& cout, MyString& str);//設置的友元
public:
private:
};

這樣cout << str << endl;這行代碼就可以調(diào)用了。

重載右移<<

如果想進行

cin>>str;代碼肯定也會報錯,因為str是MyString類型的對象,>>不認識這個。

所以,這個時候就要重載一下>>右移運算符,可以在函數(shù)文件中實現(xiàn)。(需要用全局函數(shù)配合友元進行重載)

實現(xiàn)函數(shù)

istream& operator>>(istream& cin, MyString& str)//重載右移運算符
{
	//應該先清空原來的堆區(qū)數(shù)據(jù)
	if (str.pString)//這里的pString是對象中的私有屬性,所以需要在原類中加上這個重載函數(shù)的友元聲明
	{
		delete[] str.pString;
		str.pString = NULL;
	}
	//不用急著直接將輸入的內(nèi)容傳給pString,可以先開辟臨時數(shù)組,記錄著輸入內(nèi)容。
	char buf[1024];
	cin >> buf;
	//因為是自己重載的函數(shù),剛才將str的pString刪除了,現(xiàn)在需要重新申請空間。
	str.pString = new char[strlen(buf) + 1];
	strcpy(str.pString, buf);
	str.m_Size = strlen(buf);//別忘了還要把大小考進str的size中,因為傳進來一串字符以后,對象中的長度還保持著原先的長度,所以需要進行修改。
	cout << str.m_Size << endl;
	return cin;
}

頭文件

class MyString//字符串應該是維護著一個字符數(shù)組的,在堆區(qū)
{
	friend istream& operator>>(istream& cin, MyString& str);
public:
private:
};

然后就能給str的pString賦值了。

重載右移運算符的時候的清空原來字符串中的內(nèi)容好像不太重要,刪除了也能正常運行。創(chuàng)建臨時數(shù)組記錄(數(shù)組大小夠大即可),然后將賦值,最后別忘了更改對象中的size。

重載賦值=

如果想進行:

str2 = str1

直接將兩個對象進行=運行起來代碼肯定會崩,因為:全拷貝了,刪除對象的時候會出現(xiàn)淺拷貝的問題。

如果想進行:

str2 = “abc"

直接將字符串賦值給字符串肯定也是不行的。

所以需要重載兩個不同參數(shù)的 = 運算符。(一種參數(shù)是對象,一種參數(shù)是字符串)

MyString& operator=(const MyString& str);
MyString& operator=(const char* str);

返回值必須要是MyString& ,因為使用完=運算符要返回的是自身(str2). 注意在頭函數(shù)中聲明完了以后到實現(xiàn)文件中去實現(xiàn)的時候要寫范圍MyString::,而且這個類的范圍需要寫在返回值類型的后面,函數(shù)名的前面。

重載=運算符,與重載左移和右移運算符不同,不用再像<<和>>一樣使用全局函數(shù)重載了,需要使用成員函數(shù)

頭文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class MyString
{
	friend ostream& operator<<(ostream& cout, MyString& str);
	friend istream& operator>>(istream& cin, MyString& str);
public:
	MyString(const char* str);//有參構(gòu)造函數(shù)
	MyString(const MyString& str);//拷貝構(gòu)造函數(shù)
	~MyString();//析構(gòu)(是需要的,因為這個類中還維護著一個指針,需要自己釋放)
	//重載兩個=運算符
	MyString& operator=(const MyString& str);
	MyString& operator=(const char* str);

private:
	char* pString;//維護在堆區(qū)開辟的字符數(shù)組
	int m_Size;//字符串長度(不統(tǒng)計\0)
};

實現(xiàn)文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"myString.h";
MyString & MyString::operator=(const MyString & str)
{
	//先判斷原堆區(qū)有沒有內(nèi)容,如果有先釋放。
	if (this->pString)
	{
		delete[]this->pString;
		this->pString = NULL;
	}
	//進行深拷貝
	this->pString = new char[strlen(str.pString) + 1];
	strcpy(this->pString, str.pString);
	this->m_Size = strlen(str.pString);
	return *this;
}
MyString & MyString::operator=(const char* str)
{
	//先判斷原堆區(qū)有沒有內(nèi)容,如果有先釋放。
	if (this->pString)
	{
		delete[]this->pString;
		this->pString = NULL;
	}
	//進行深拷貝
	this->pString = new char[strlen(str) + 1];
	strcpy(this->pString, str);
	this->m_Size = strlen(str);
	return *this;
}

Test文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include "myString.h";

int main()
{
	MyString str = "abc";//調(diào)用默認構(gòu)造
	MyString str2 = "bcd";
	str = str2;
	MyString str3 = "abc";
	cout << str << endl;//bcd
	cout << str3 << endl;//abc
	return 0;
}

重載中括號[ ]

如果項進行

str2[0] = 'a';

是不可以的,因為[ ]不認識str。

所以需要重載中括號[]。直接使用成員函數(shù)進行重載。

//在頭文件中:
char operator[](int index);
//在實現(xiàn)函數(shù)中:
char MyString::operator[](int index)//重載中括號
{
	return this->pString[index];
}

正常來說就返回char類型的數(shù)值就行了,這樣就可讀了。

但是如果想將str2p[1]作為運算左值來修改,那么就需要返回本體char&

//在頭文件中:
char& operator[](int index);
//在實現(xiàn)函數(shù)中:
char& MyString::operator[](int index)//重載中括號
{
	return this->pString[index];
}
//在Test文件中
int main()
{
	MyString str2 = "bcd";
	cout << str2[1] << endl;//c
	str2[1] = 'z';
	cout << str2[1] << endl;//z
	return 0;
}

重載加號+

如果想實現(xiàn):

MyString str3 = "abc";
MyString str4 = "def";
MyString str5 = str3 + str4;
MyString str6 = str5+"abc";

這樣肯定會報錯,因為+不認識對象,也不認識這樣的字符串

所以,需要對+進行重載,使用的還是成員函數(shù),只有一個參數(shù)。

從題意得,傳進去一個對象,然后返回出一個對象,或者是傳進去一個字符串,返回出一個對象。(前提是將第一個傳進去的看作是調(diào)用對象)

頭文件

MyString operator+(const MyString& str);
MyString operator+(const char* str);

實現(xiàn)文件

//重載+運算符
MyString MyString:: operator+(const MyString& str)
{
	//本身abc,傳入的是def,剛開始應該先計算一下需要開辟的內(nèi)存空間。
	int newSize = this->m_Size + strlen(str.pString) + 1;
	char* temp = new char[newSize];//然后將這塊空間開辟出來,temp指針指向它。
	memset(temp, 0, newSize);//將空間里面的內(nèi)容全部清空。
	strcat(temp, this->pString);//將this->pString扔進了temp中。
	strcat(temp, str.pString);//然后再將str字符串扔進去,這樣它們就自己結(jié)合了。
	//但是創(chuàng)建好的新的字符串不能直接返回,因為需要返回一個對象
	//所以就創(chuàng)建一個新的對象,然后通過構(gòu)造函數(shù)將字符串賦給新對象,最后再返回新對象。
	MyString newString = temp;
	//還有一點,創(chuàng)建的類是空間temp用完了需要釋放
	delete[]temp;
	return newString;	
}
MyString MyString:: operator+(const char* str)
{
	//本身abc,傳入的是def,剛開始應該先計算一下需要開辟的內(nèi)存空間。
	int newSize = this->m_Size + strlen(str) + 1;
	char* temp = new char[newSize];//然后將這塊空間開辟出來,temp指針指向它。
	memset(temp, 0, newSize);//將空間里面的內(nèi)容全部清空。
	strcat(temp, this->pString);//將this->pString扔進了temp中。
	strcat(temp, str);//然后再將str字符串扔進去,這樣它們就自己結(jié)合了。
	//但是創(chuàng)建好的新的字符串不能直接返回,因為需要返回一個對象
	//所以就創(chuàng)建一個新的對象,然后通過構(gòu)造函數(shù)將字符串賦給新對象,最后再返回新對象。
	MyString newString = temp;
	//還有一點,創(chuàng)建的類是空間temp用完了需要釋放
	delete[]temp;
	return newString;
}

兩種+重載函數(shù)幾乎一樣

TEST文件

int main()
{
	MyString str3 = "abc";
	MyString str4 = "def";
	MyString str5 = str3 + str4;
	MyString str6 = str5 + "abc";
	cout << str5 << endl;//abcdef
	cout << str6 << endl;//abcdefabc
	return 0;
}

重載==

ps補充:strcmp函數(shù)中,如果兩個字符串相等,那么就返回0,如果不相等,那么就返回1。

也是提供兩種重載函數(shù):

//頭文件:
//重載==運算符
bool operator==(const MyString& str);
bool operator==(const char* str);
//實現(xiàn)文件:
//重載==運算符
bool MyString::operator==(const MyString & str)
{
	if (strcmp(this->pString, str.pString) == 0)
		return true;
	else
		return false;
}
bool MyString::operator==(const char* str)
{
	if (strcmp(this->pString, str) == 0)
		return true;
	else
		return false;
}
//Test文件
int main()
{
	MyString str3 = "abc";
	MyString str4 = "def";
	MyString str5 = str3 + str4;
	cout << str5 << endl;//abcdef
	if (str5 == str5)
	{
		cout << "是相等的" << endl;
	}
	else
	{
		cout << "是不相等的" << endl;
	}
	//結(jié)果是相等的。
	return 0;
}

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內(nèi)容! 

相關文章

  • mysate中stat命令的實現(xiàn)方法

    mysate中stat命令的實現(xiàn)方法

    這篇文章主要介紹了mysate中stat命令的實現(xiàn)方法,stat作用:用來顯示文件的詳細信息,包括inode, atime, mtime, ctime,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2022-10-10
  • Opencv二幀差法檢測運動目標與提取輪廓

    Opencv二幀差法檢測運動目標與提取輪廓

    這篇文章主要為大家詳細介紹了Opencv使用二幀差法檢測運動目標與提取輪廓,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • STL 的string類怎么啦

    STL 的string類怎么啦

    在我們研究string類犯了什么毛病之前,還讓我先說一下如何了解一個C++的類。我們要了解一個C++的類,一般來說,要從三個方面入手
    2013-11-11
  • C++之異常處理詳解

    C++之異常處理詳解

    C++中處理異常的過程是這樣的:在執(zhí)行程序發(fā)生異常,可以不在本函數(shù)中處理,而是拋出一個錯誤信息,把它傳遞給上一級的函數(shù)來解決,上一級解決不了,再傳給其上一級,由其上一級處理
    2013-08-08
  • C語言實現(xiàn)貪吃蛇小黑窗

    C語言實現(xiàn)貪吃蛇小黑窗

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)貪吃蛇小黑窗,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • ros項目調(diào)試:vscode下配置開發(fā)ROS項目的詳細教程

    ros項目調(diào)試:vscode下配置開發(fā)ROS項目的詳細教程

    這篇文章主要介紹了ros項目調(diào)試:vscode下配置開發(fā)ROS項目,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • C語言經(jīng)典算法例題求100-999之間的“水仙花數(shù)”

    C語言經(jīng)典算法例題求100-999之間的“水仙花數(shù)”

    本文的主要內(nèi)容,設計一個程序,找出100-999之間的“水仙花數(shù)”,需要的朋友可以參考下
    2015-07-07
  • C++實現(xiàn)旋轉(zhuǎn)掃描儀的示例代碼

    C++實現(xiàn)旋轉(zhuǎn)掃描儀的示例代碼

    旋轉(zhuǎn)掃描儀(Rotating?Scanner),也稱為旋轉(zhuǎn)掃描儀或圓形掃描儀,是一種用于獲取圖像和文檔的設備,下面就跟隨小編一起來學習一下如何使用C++實現(xiàn)旋轉(zhuǎn)掃描儀功能吧
    2024-02-02
  • C語言清除scanf()緩存的案例講解

    C語言清除scanf()緩存的案例講解

    今天小編就為大家分享一篇關于C語言清除scanf()緩存的案例講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • C語言變長數(shù)組 struct中char data[0]的用法詳解

    C語言變長數(shù)組 struct中char data[0]的用法詳解

    下面小編就為大家?guī)硪黄狢語言變長數(shù)組 struct中char data[0]的用法詳解。小編覺得挺不錯的現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01

最新評論