当前位置: 首页 > news >正文

网站建设关键词软文推广模板

网站建设关键词,软文推广模板,网页版小红书,进出口外贸公司嘿嘿,家人们,今天咱们来模拟实现string,好啦,废话不多讲,开干! 1:string.h 1.1:构造函数与拷贝构造函数 1.1.1:写法一 1.1.2:写法二(给缺省值) 1.2:赋值运算符重载与operatror[]获取元素 1.3:容量与迭代器 1.4:reserve与resize 1.5:清空与判断是否为空 1.6:push_back与…

嘿嘿,家人们,今天咱们来模拟实现string,好啦,废话不多讲,开干!


1:string.h

1.1:构造函数与拷贝构造函数

1.1.1:写法一

1.1.2:写法二(给缺省值)

1.2:赋值运算符重载与operatror[]获取元素

1.3:容量与迭代器

1.4:reserve与resize

1.5:清空与判断是否为空

1.6:push_back与append

1.7:insert

1.7.1:插入字符

1.7.2:插入字符串

1.8:erase

1.9:operator+=

1.9.1:添加字符

1.9.2:添加字符串

1.91:find

1.91.1:查找字符

1.91.2:查找字符串 

1.92:substr与swap

1.93:非成员函数的重载

1.93.1:流插入与流提取的重载

1.93.2:其他非成员函数的重载

2:Test.cpp

2.1:构造函数与拷贝构造

2.1.1:测试写法一

2.1.2:测试写法二

2.2:测试赋值运算符重载与[]获取元素

2.3:测试迭代器与容量

2.4:测试reserve与resize 

2.4.1:测试resize

2.4.2:测试reserve

2.5:测试push_back与append

2.6:测试insert

2.6.1:测试插入字符

2.6.2:测试插入字符串

2.7:测试erase

2.8:测试operator+=

2.9:测试find

2.91:测试substr与swap

2.92:测试流插入与流提取

2.92.1:第一版流提取

2.92.2:第二版流提取

2.93:测试其他非成员函数

3:知识补充

3.1:深拷贝与浅拷贝

3.1.1:浅拷贝

​3.1.2:深拷贝

4:总代码

4.1:string.h

4.2:Test.cpp


1:string.h

1.1:构造函数与拷贝构造函数

1.1.1:写法一

#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;//避免与库中的string冲突,因此使用命名空间
namespace MyString
{class string{public:string():_str(new char[1]), _size(0),_capacity(0){//空字符串只有\0,_str[0] = '\0';}//构造非空字符串string(const char * str)//开辟空间,多开辟个空间存放\0:_str(new char[strlen(str) + 1]){//开辟空间_capacity = _size = strlen(str);//拷贝数据strcpy(_str, str);}//拷贝构造函数//s2(s1),使用s1拷贝构造s2string(string & s){//开辟空间char* temp = new char[s._capacity + 1];_str = temp;_capacity = s._capacity;_size = s._size;//拷贝数据strcpy(_str, s._str);}//析构函数~string(){delete[] _str;_size = _capacity = 0;}private://定义成员变量并且给缺省值char* _str;int   _size;int   _capacity;};}

1.1.2:写法二(给缺省值)

#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;//避免与库中的string冲突,因此使用命名空间
namespace MyString
{class string{public://string()//	:_str(new char[1])//	, _size(0)//	,_capacity(0)//{//	//空字符串只有\0,//	_str[0] = '\0';//}构造非空字符串//string(const char * str)//	//开辟空间,多开辟个空间存放\0//	:_str(new char[strlen(str) + 1])//{//	//开辟空间//	_capacity = _size = strlen(str);//	//拷贝数据//	strcpy(_str, str);//}//给缺省值,构造空字符串时使用缺省值string(const char* str = "")//开辟空间,多开辟个空间存放\0:_str(new char[strlen(str) + 1]){//开辟空间_capacity = _size = strlen(str);//拷贝数据strcpy(_str, str);}/*拷贝构造函数s2(s1),使用s1拷贝构造s2*/string(string & s){//开辟空间char* temp = new char[s._capacity + 1];_str = temp;_capacity = s._capacity;_size = s._size;//拷贝数据strcpy(_str, s._str);}//析构函数~string(){delete[] _str;_size = _capacity = 0;}private://定义成员变量并且给缺省值char* _str = nullptr;int   _size = 0;int   _capacity = 0;};}

1.2:赋值运算符重载与operatror[]获取元素

		//s1 = s2 this---->s1   s2----->s//赋值运算符重载string & operator =(string & s){//开辟新空间char * temp = new char[s._capacity + 1];//释放旧空间delete _str;//拷贝数据strcpy(temp, s._str);//指向新空间_str = temp;_size = s._size;_capacity = s._capacity;return *this;}//T &,返回引用同样可以提高效率,有返回值的目的是为了支持连续赋值.char & operator[](size_t position){assert(position < _size);return _str[position];}//const成员函数,给const对象调用,与上面构成函数重载const char& operator[](size_t position) const{assert(position < _size);return _str[position];}

1.3:容量与迭代器

迭代器呢其实是一个类指针,因此我们在模拟实现的时候,直接通过指针来进行模拟即可~

#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;//避免与库中的string冲突,因此使用命名空间
namespace MyString
{class string{typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}//设置成员函数const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}//capacitysize_t size(){return _size;}size_t capacity(){return _capacity;}private://定义成员变量并且给缺省值char* _str = nullptr;int   _size = 0;int   _capacity = 0;};}

1.4:reserve与resize

我们来回顾下reserve与resize的相关知识 

1:reserve

  • 比size小不变化
  • 比size大但小于capacity也不发生变化
  • 比capacity大才会进行扩容

因此我们只要判断是否比capacity大

2:resize

  • 比size小则进行删除.

  • 比size大但小于capacity会改变size,并用\0插入.
  • 比capacity大,会先改变size的大小同时进行扩容.

		//仅需判断是否比capacity大void reserve(size_t n){if(n > _capacity){//开辟新空间char* temp = new char[n + 1];//拷贝数据strcpy(temp, _str);//释放旧空间delete[] _str;//指向新空间_str = temp;_capacity = n;}}void resize(size_t n,char ch = '\0'){//比size小则会进行删除if (n <= _size){_str[n] = ch;}//比size大比capacity小会改变size,并且用\0插入else if( n > _size && n <= _capacity){_size = n;}//比capacity大, 会先改变size的大小同时进行扩容.else{//扩容reserve(n);for(size_t i = _size; i < _capacity ; i++){_str[i] = ch;}_size = n;}}

1.5:清空与判断是否为空

		//只清除有效字符,不改变底层空间void clear(){_str[0] = '\0';_size = 0;}bool empty()const{return _size == 0;}

这里博主就不带着uu们测试啦,感兴趣的uu可以自己下去测试下~ 

1.6:push_back与append

//Modifiersvoid push_back(char ch){//检查容量if (_size == _capacity)//二倍扩容reserve(_capacity == 0 ? 4 : 2 * _capacity);_str[_size] = ch;_size++;_str[_size] = '\0';}void append(const char * str){assert(str);//求出添加的字符串的长度int length = strlen(str);//判断添加后的有效字符数量是否越过容量if (_size + length > _capacity)reserve(_size + length);//_str + _size的位置为\0strcpy(_str + _size, str);_size += length;}

1.7:insert

1.7.1:插入字符

	string & insert(size_t position,char ch){assert(position <= _size);if (_size == _capacity)//二倍扩容reserve(_capacity == 0 ? 4 : 2 * _capacity);//从后向前挪动覆盖for(int i = _size - 1; i >= position ;i--){_str[i + 1] = _str[i];}_str[position] = ch;_size++;_str[_size] = '\0';return *this;}

1.7.2:插入字符串

string & insert(size_t position,const char * str){assert(position <= _size);int length = strlen(str);if (_size + length > _capacity)reserve(_size + length);//从后向前挪动覆盖//_size + length - 1表示挪动的字符串的重点,positon + length表示挪动的字符串的起点for(int i = _size + length - 1; i >= position + length; i--){_str[i] = _str[i - length];}//拷贝数据strncpy(_str + position, str, length);_size += length;_str[_size] = '\0';return *this;}

1.8:erase

		void erase(size_t position = 0,size_t len = -1){//防止越界assert(position < _size);//len == -1:如果 len 为 -1,表示删除到字符串末尾。//len >= _size - pos,如果 len 超过从 pos 开始的剩余字符长度,同样认为是删除到末尾。if(len == -1 || len >= _size - position){_str[position] = '\0';_size = position;}else{//将 pos + len 后的字符串内容复制到 pos 位置,从而覆盖中间 len 长度的字符,实现删除操作strcpy(_str + position, _str + position + len);}}

1.9:operator+=

1.9.1:添加字符

		string& operator+=(char ch){push_back(ch);return *this;}

1.9.2:添加字符串

		string& operator+=(const char * str){append(str);return *this;}

1.91:find

1.91.1:查找字符

//添加const修饰,令const成员与非const成员均可调用size_t find(char ch, size_t pos = 0) const{for(size_t i = pos; i < _size;i++){if (_str[i] == ch)return i;}return -1;}

1.91.2:查找字符串 

		const char * c_str()const{return _str;}//添加const修饰,令const成员与非const成员均可调用size_t find(const char * str,size_t pos = 0	)const{const char* p = strstr(_str + pos, str);if(p != NULL){//指针 - 指针得到对应的首字符下标return p - _str;}return -1;}

1.92:substr与swap

		string substr(size_t pos = 0, size_t len = -1){string substr;//len == -1:如果 len 为 -1,表示全部获取。//len > _size - pos,如果 len 超过从 pos 开始的剩余字符长度,同样认为是全部获取if(len > _size - pos || len == -1){for(size_t i = 0; i < _size; i++){substr += _str[i];}}else{for(size_t i = pos; i < pos + len;i++){substr += _str[i];}}return substr;}//s1.swap(s2)void swap(string & str){std::swap(_str, str._str);std::swap(_size, str._size);std::swap(_capacity, str._capacity);}

1.93:非成员函数的重载

1.93.1:流插入与流提取的重载

	ostream& operator<<(ostream& _cout,MyString::string& str){for (auto ch : str){cout << ch;}return _cout;}istream& operator>>(istream& _cin, MyString::string& str){第一版:会导致空间的浪费//char ch;_cin是无法读到\n与' '的//ch = _cin.get();清空字符//str.clear();//while (ch != '\n' && ch != ' ')//{//	str += ch;//	ch = _cin.get();//}//return _cin;//第二版char ch;ch = _cin.get();//底层给个buffchar buff[128];size_t i = 0;//将原本的字符清空str.clear();//cin无法读取' '与'\n'while (ch != '\n' && ch != ' '){buff[i++] = ch;//最后一个字符设置为\0if(i == 127){buff[i] = '\0';str += buff;}//持续读取字符ch = _cin.get();}if(i > 0){buff[i] = '\0';str += buff;}return _cin;} 
}
按照常规方式,流提取按照上面的第一版方式进行重载即可,但是,底层其实是给了buff,目的是: 防止空间的浪费,因为按照常规方式重载的话,那么在 扩容的时候一般是1.5倍或者2倍扩容,而通过给一个buff,能够最大程度地防止空间的浪费.

1.93.2:其他非成员函数的重载

	//会先调用此swap,有现成的,吃现成的,不使用模版里面的swapvoid swap(string& x, string& y){x.swap(y);}//自定义类型传值传参会调用拷贝构造,因此需要传引用bool operator==(const MyString::string& str1, const  MyString::string& str2){int result = strcmp(str1.c_str(), str2.c_str());return result == 0;}bool operator<(const  MyString::string& str1, const MyString::string& str2){int result = strcmp(str1.c_str(), str2.c_str());return result < 0;}bool operator>(const  MyString::string& str1, const  MyString::string& str2){int result = strcmp(str1.c_str(), str2.c_str());return result > 0;}bool operator<=(const  MyString::string& str1, const  MyString::string& str2){return (str1 < str2) || (str1 == str2);}bool operator>=(const  MyString::string& str1, const  MyString::string& str2){return !(str1 < str2);}bool operator!=(const  MyString::string& str1, const  MyString::string& str2){return !(str1 == str2);}

2:Test.cpp

2.1:构造函数与拷贝构造

2.1.1:测试写法一

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestConstructionAndCopyConstruction()
{MyString::string s1;MyString::string s2("hello world");MyString::string s3(s2);
}
int main()
{TestConstructionAndCopyConstruction();return 0;
}

2.1.2:测试写法二

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestConstructionAndCopyConstruction()
{MyString::string s1;MyString::string s2("hello world");MyString::string s3(s2);
}
int main()
{TestConstructionAndCopyConstruction();return 0;
}

2.2:测试赋值运算符重载与[]获取元素

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestAssignmentOperatorOverloadingAndElementAccess()
{MyString::string s1;MyString::string s2("hello world");const MyString::string s3("hello Linux");s1 = s2;cout <<"s1[0]:>" << s1[0] << endl;cout <<"s3[6]:>" << s3[6] << endl;
}
int main()
{TestAssignmentOperatorOverloadingAndElementAccess();return 0;
}

2.3:测试迭代器与容量

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestIteratorAndCapacity()
{MyString::string s1;MyString::string s2("hello world");s1 = s2;for(auto & element : s2){cout << element << endl;}cout <<"s2.size()" << s2.size() << endl;cout <<"s2.capacity()" << s2.capacity() << endl;
}int main()
{TestIteratorAndCapacity();return 0;
}

2.4:测试reserve与resize 

2.4.1:测试resize

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestResize()
{MyString::string str("hello world");//比size小则进行删除str.resize(10);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << endl;//比size大但小于capacity会用改变size,并用\0插入str.resize(13);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << endl;//比capacity大,会先改变size的大小同时进行扩容str.resize(20);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;
}int main()
{TestResize();return 0;
}

2.4.2:测试reserve

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestRserve()
{MyString::string str("hello world");cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << "reserver后" << endl;cout << endl;//比size小不变化str.reserve(10);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << endl;//比size大但小于capacity也不发生变化str.reserve(13);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << endl;//比capacity大才会进行扩容str.reserve(20);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;
}int main()
{TestRserve();return 0;
}

2.5:测试push_back与append

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestPushBackAndAppend()
{MyString::string str;str.append("hello world");str.push_back('x');
}int main()
{TestPushBackAndAppend();return 0;
}

2.6:测试insert

2.6.1:测试插入字符

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestInsert() 
{MyString::string str("hello world");//在下标为5的位置插入字符hstr.insert(5, 'h');
}int main()
{TestInsert();return 0;
}

2.6.2:测试插入字符串

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestInsert() 
{MyString::string str("hello world");//在下标为5的位置插入字符hstr.insert(5, 'h');str.insert(2, "Linux");
}int main()
{TestInsert();return 0;
}

2.7:测试erase

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestErase()
{MyString::string str("hello world");str.erase(2, 4);
}int main()
{TestErase();return 0;
}

 

2.8:测试operator+=

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void Test()
{MyString::string str("hello");str += ' ';str += "Linux";
}int main()
{Test();return 0;
}

2.9:测试find

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestFind() 
{MyString::string str("hello Linux");cout << str.find('l', 2) << endl;cout << str.find("Linux", 2) << endl;
}int main()
{TestFind();return 0;
}

2.91:测试substr与swap

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestSwapAndSubstr()
{MyString::string s1("hello Linux");MyString::string s2("hello bit");MyString::string temp = s1.substr(6, 5);cout << "交换前" << endl;cout << "s1:>" << s1 << endl;cout << "s2:>" << s2 << endl;cout <<"temp:>" << temp << endl;s1.swap(s2);cout << "交换后" << endl;cout <<"s1:>" << s1 << endl;cout <<"s2:>" << s2 << endl;
}
int main()
{TestSwapAndSubstr();return 0;
}

2.92:测试流插入与流提取

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestStreamInsertionAndStreamExtraction()
{MyString::string s1;cin >> s1;cout << s1 << endl;cout << "s1.size:>" << s1.size() << endl;cout << "s1.capacity:>" << s1.capacity() << endl;
}
int main()
{TestStreamInsertionAndStreamExtraction();return 0;
}

2.92.1:第一版流提取

2.92.2:第二版流提取

2.93:测试其他非成员函数

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"
void TestOtherFunction()
{MyString::string s1("hello world");MyString::string s2("hello bit");swap(s1, s2);s1.swap(s2);cout << s1.c_str() << endl;cout << s2.c_str() << endl;cout << (s1 == s2) << endl;cout << (s1 >= s2) << endl;cout << (s1 > s2) << endl;cout << (s1 < s2) << endl;cout << (s1 <= s2) << endl;cout << (s1 != s2) << endl;
}int main()
{TestOtherFunction();return 0;
}

3:知识补充

3.1:深拷贝与浅拷贝

在讲深浅拷贝之前,我们来看一个现象

我们可以清晰地看到,s2与s3的地址一样,这是为什么呢,因为博主将显示定义的拷贝构造函数给屏蔽了,因此在拷贝构造s3时会调用编译器默认的拷贝构造函数,那么这就会导致一个问题:

s2与s3共用同一块内存空间,在释放时同一块内存空间被释放多次而会引起程序崩溃,这种方式被称作浅拷贝.

3.1.1:浅拷贝

浅拷贝:又被称作位拷贝,编译器直接是将另外一个对象的值拷贝复制过来.如果对象中管理资源,那么最后就会导致多个对象共享一份资源,当一个对象销毁时就会将资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还是有效的,那么因此当继续对资源进行操作时,就会发生访问违规~

举一个简单例子

就像一个家庭中有两个孩子,但父母只买了一份玩具,两个孩子愿意一块玩,则万事大吉,万一不想分享就你争我抢,玩具损坏.
那么该如何解决浅拷贝的问题呢,用深拷贝就可以即每个对象都有一份独立的资源,不要和其他对象共享。父母给每个孩子都买一份玩具,各自玩各自的就不会有存在任何矛盾.  

 3.1.2:深拷贝

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出,一般情况都是按照深拷贝方式提供.

4:总代码

4.1:string.h

#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;//避免与库中的string冲突,因此使用命名空间
namespace MyString
{class string{typedef char* iterator;typedef const char* const_iterator;public://string()//	:_str(new char[1])//	, _size(0)//	,_capacity(0)//{//	//空字符串只有\0,//	_str[0] = '\0';//}构造非空字符串//string(const char * str)//	//开辟空间,多开辟个空间存放\0//	:_str(new char[strlen(str) + 1])//{//	//开辟空间//	_capacity = _size = strlen(str);//	//拷贝数据//	strcpy(_str, str);//}//给缺省值,构造空字符串时使用缺省值string(const char* str = "")//开辟空间,多开辟个空间存放\0:_str(new char[strlen(str) + 1]){//开辟空间_capacity = _size = strlen(str);//拷贝数据strcpy(_str, str);}/*拷贝构造函数s2(s1),使用s1拷贝构造s2*/string(string& s){//开辟空间char* temp = new char[s._capacity + 1];_str = temp;_capacity = s._capacity;_size = s._size;//拷贝数据strcpy(_str, s._str);}//s1 = s2 this---->s1   s2----->s//赋值运算符重载string& operator =(string& s){//开辟新空间char* temp = new char[s._capacity + 1];//释放旧空间delete _str;//拷贝数据strcpy(temp, s._str);//指向新空间_str = temp;_size = s._size;_capacity = s._capacity;return *this;}//T &,返回引用同样可以提高效率,有返回值的目的是为了支持连续赋值.char& operator[](size_t position){assert(position < _size);return _str[position];}//const成员函数,给const对象调用,与上面构成函数重载const char& operator[](size_t position) const{assert(position < _size);return _str[position];}/////iteraoriterator begin(){return _str;}iterator end(){return _str + _size;}//设置成员函数const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}//capacitysize_t size(){return _size;}size_t capacity(){return _capacity;}//仅需判断是否比capacity大void reserve(size_t n){if (n > _capacity){//开辟新空间char* temp = new char[n + 1];//拷贝数据strcpy(temp, _str);//释放旧空间delete[] _str;//指向新空间_str = temp;_capacity = n;}}void resize(size_t n, char ch = '\0'){//比size小则会进行删除if (n <= _size){_str[n] = ch;}//比size大比capacity小会改变size,并且用\0插入else if (n > _size && n <= _capacity){_size = n;}//比capacity大, 会先改变size的大小同时进行扩容.else{//扩容reserve(n);for (size_t i = _size; i < _capacity; i++){_str[i] = ch;}_size = n;}}//Modifiersvoid push_back(char ch){//检查容量if (_size == _capacity)//二倍扩容reserve(_capacity == 0 ? 4 : 2 * _capacity);_str[_size] = ch;_size++;_str[_size] = '\0';}void append(const char* str){assert(str);//求出添加的字符串的长度int length = strlen(str);//判断添加后的有效字符数量是否越过容量if (_size + length > _capacity)reserve(_size + length);//_str + _size的位置为\0strcpy(_str + _size, str);_size += length;}string& insert(size_t position, char ch){assert(position <= _size);if (_size == _capacity)//二倍扩容reserve(_capacity == 0 ? 4 : 2 * _capacity);//从后向前挪动覆盖for (int i = _size - 1; i >= position; i--){_str[i + 1] = _str[i];}_str[position] = ch;_size++;_str[_size] = '\0';return *this;}void clear(){_str[0] = '\0';_size = 0;}bool empty()const{return _size == 0;}string& insert(size_t position, const char* str){assert(position <= _size);int length = strlen(str);if (_size + length > _capacity)reserve(_size + length);//从后向前挪动覆盖//_size + length - 1表示挪动的字符串的重点,positon + length表示挪动的字符串的起点for (int i = _size + length - 1; i >= position + length; i--){_str[i] = _str[i - length];}//拷贝数据strncpy(_str + position, str, length);_size += length;_str[_size] = '\0';return *this;}void erase(size_t position = 0, size_t len = -1){//防止越界assert(position < _size);//len == -1:如果 len 为 -1,表示删除到字符串末尾。//len >= _size - pos,如果 len 超过从 pos 开始的剩余字符长度,同样认为是删除到末尾。if (len == -1 || len >= _size - position){_str[position] = '\0';_size = position;}else{//将 pos + len 后的字符串内容复制到 pos 位置,从而覆盖中间 len 长度的字符,实现删除操作strcpy(_str + position, _str + position + len);}}string& operator+=(char ch){push_back(ch);return *this;}string& operator+=(const char * str){append(str);return *this;}const char * c_str()const{return _str;}//添加const修饰,令const成员与非const成员均可调用size_t find(char ch, size_t pos = 0) const{for(size_t i = pos; i < _size;i++){if (_str[i] == ch)return i;}return -1;}//添加const修饰,令const成员与非const成员均可调用size_t find(const char * str,size_t pos = 0	)const{const char* p = strstr(_str + pos, str);if(p != NULL){//指针 - 指针得到对应的首字符下标return p - _str;}return -1;}string substr(size_t pos = 0, size_t len = -1){string substr;//len == -1:如果 len 为 -1,表示全部获取。//len > _size - pos,如果 len 超过从 pos 开始的剩余字符长度,同样认为是全部获取if(len > _size - pos || len == -1){for(size_t i = 0; i < _size; i++){substr += _str[i];}}else{for(size_t i = pos; i < pos + len;i++){substr += _str[i];}}return substr;}//s1.swap(s2)void swap(string & str){std::swap(_str, str._str);std::swap(_size, str._size);std::swap(_capacity, str._capacity);}//析构函数~string(){delete[] _str;_size = _capacity = 0;}private://定义成员变量并且给缺省值char* _str = nullptr;int   _size = 0;int   _capacity = 0;};//Non-member_function_overloadsostream& operator<<(ostream& _cout,MyString::string& str){for (auto ch : str){cout << ch;}return _cout;}istream& operator>>(istream& _cin, MyString::string& str){第一版:会导致空间的浪费//char ch;_cin是无法读到\n与' '的//ch = _cin.get();清空字符//str.clear();//while (ch != '\n' && ch != ' ')//{//	str += ch;//	ch = _cin.get();//}//return _cin;//第二版char ch;ch = _cin.get();//底层给个buffchar buff[128];size_t i = 0;//将原本的字符情况str.clear();//cin无法读取' '与'\n'while (ch != '\n' && ch != ' '){buff[i++] = ch;//最后一个字符设置为\0if(i == 127){buff[i] = '\0';str += buff;}//持续读取字符ch = _cin.get();}if(i > 0){buff[i] = '\0';str += buff;}return _cin;}//会先调用此swap,有现成的,吃现成的,不使用模版里面的swapvoid swap(string& x, string& y){x.swap(y);}//自定义类型传值传参会调用拷贝构造,因此需要传引用bool operator==(const MyString::string& str1, const  MyString::string& str2){int result = strcmp(str1.c_str(), str2.c_str());return result == 0;}bool operator<(const  MyString::string& str1, const MyString::string& str2){int result = strcmp(str1.c_str(), str2.c_str());return result < 0;}bool operator>(const  MyString::string& str1, const  MyString::string& str2){int result = strcmp(str1.c_str(), str2.c_str());return result > 0;}bool operator<=(const  MyString::string& str1, const  MyString::string& str2){return (str1 < str2) || (str1 == str2);}bool operator>=(const  MyString::string& str1, const  MyString::string& str2){return !(str1 < str2);}bool operator!=(const  MyString::string& str1, const  MyString::string& str2){return !(str1 == str2);}
}

4.2:Test.cpp

#define _CRT_SECURE_NO_WARNINGS
#include "String.h"void TestConstructionAndCopyConstruction()
{MyString::string s1;MyString::string s2("hello world");MyString::string s3(s2);
}void TestAssignmentOperatorOverloadingAndElementAccess()
{MyString::string s1;MyString::string s2("hello world");const MyString::string s3("hello Linux");s1 = s2;cout <<"s1[0]:>" << s1[0] << endl;cout <<"s3[6]:>" << s3[6] << endl;
}void TestIteratorAndCapacity()
{MyString::string s1;MyString::string s2("hello world");s1 = s2;for(auto & element : s2){cout << element;}cout << endl;cout <<"s2.size():>" << s2.size() << endl;cout <<"s2.capacity():>" << s2.capacity() << endl;
}void TestResize()
{MyString::string str("hello world");//比size小则进行删除str.resize(10);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << endl;//比size大但小于capacity会用改变size,并用\0插入str.resize(13);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << endl;//比capacity大,会先改变size的大小同时进行扩容str.resize(20);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;
}void TestRserve()
{MyString::string str("hello world");cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << "reserver后" << endl;cout << endl;//比size小不变化str.reserve(10);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << endl;//比size大但小于capacity也不发生变化str.reserve(13);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;cout << endl;//比capacity大才会进行扩容str.reserve(20);cout << "size:>" << str.size() << endl;cout << "capacity:>" << str.capacity() << endl;
}void TestPushBackAndAppend()
{MyString::string str;str.append("hello world");str.push_back('x');
}
void TestInsert() 
{MyString::string str("hello world");//在下标为5的位置插入字符hstr.insert(5, 'h');str.insert(2, "Linux");
}void TestErase()
{MyString::string str("hello world");str.erase(2, 4);
}void Test()
{MyString::string str("hello");str += ' ';str += "Linux";
}void TestFind() 
{MyString::string str("hello Linux");cout << str.find('l', 2) << endl;cout << str.find("Linux", 2) << endl;
}
void TestSwapAndSubstr()
{MyString::string s1("hello Linux");MyString::string s2("hello bit");MyString::string temp = s1.substr(6, 5);cout << "交换前" << endl;cout << "s1:>" << s1 << endl;cout << "s2:>" << s2 << endl;cout <<"temp:>" << temp << endl;s1.swap(s2);cout << "交换后" << endl;cout <<"s1:>" << s1 << endl;cout <<"s2:>" << s2 << endl;
}void TestStreamInsertionAndStreamExtraction()
{MyString::string s1;cin >> s1;cout << s1 << endl;cout << "s1.size:>" << s1.size() << endl;cout << "s1.capacity:>" << s1.capacity() << endl;
}void TestOtherFunction()
{MyString::string s1("hello world");MyString::string s2("hello bit");swap(s1, s2);s1.swap(s2);cout << s1.c_str() << endl;cout << s2.c_str() << endl;cout << (s1 == s2) << endl;cout << (s1 >= s2) << endl;cout << (s1 > s2) << endl;cout << (s1 < s2) << endl;cout << (s1 <= s2) << endl;cout << (s1 != s2) << endl;
}int main()
{TestConstructionAndCopyConstruction();TestAssignmentOperatorOverloadingAndElementAccess();TestIteratorAndCapacity();TestResize();TestRserve();TestPushBackAndAppend();TestInsert();TestErase();Test();TestFind();TestSwapAndSubstr();TestStreamInsertionAndStreamExtraction();TestOtherFunction();return 0;
}

好啦,uu们,string的模拟实现这部分滴详细内容博主就讲到这里啦,如果uu们觉得博主讲的不错的话,请动动你们滴小手给博主点点赞,你们滴鼓励将成为博主源源不断滴动力,同时也欢迎大家来指正博主滴错误~

http://www.wooajung.com/news/23418.html

相关文章:

  • b站大全不收费青岛网站
  • 做网课网站杭州百度百家号seo优化排名
  • 厦门首屈一指的网站建设公司营销推广的特点是
  • 创建网站需要哪些工作优秀网站设计案例
  • 城市管理如何宣传市建设网站网站如何优化
  • 做哪些网站好网站注册要多少钱
  • 企业网站建设哪家专业今日头条权重查询
  • 企业建网站费用百度大数据查询
  • 浩森宇特北京做网站哪里可以学网络运营和推广
  • vs开发网站开发教程产品推广思路
  • 安丘网站建设aqfeifan谷歌浏览器官网手机版
  • 惠阳网站制作公司自己在家怎么做电商
  • 做网站菠菜什么意思百度新闻官网首页
  • idc网站模版百度在线客服
  • 长沙微信网站制作百度投诉中心人工电话号码
  • 怎么用织梦系统建一个网站武汉网络营销推广
  • 英文搜索网站深圳网络推广代运营
  • 有网站模板如何预览云和数据培训机构怎么样
  • 相亲网站建设方案南京企业网站排名优化
  • 自己做的网站怎么添加采集模块如何创建网址
  • 网站仿做爱站网长尾关键词挖掘
  • 辽宁建设厅新网站2022世界足球排行榜
  • 什么app做网站直销的八大课程
  • 建设项目环保竣工验收备案网站企业关键词优化价格
  • 一个真正的网站需要怎么做sem推广
  • wordpress谷歌地图深圳seo优化推广
  • 可以做网站引导页的页面武汉百度快照优化排名
  • 算命先生的网站怎么做seo网站关键词排名优化公司
  • 企业网站的类型有哪些网络优化培训骗局
  • 个人备案网站百度收录学网络营销