专题网站可以做什么,服务器做的网站怎么使用教程,北京做vr网站,福建省建设职业管理中心网站目录 一.实现string类
1.string的构造及析构
2.string类的遍历
3.string类的插入和删除
4.string类的空间处理
5.string类的查找
6.string类的输出和输入
7.string类的常用判断
二.整体代码
1.string.h
2.string.cpp 一.实现string类
在前一节中我们了解了STL中stri…目录 一.实现string类
1.string的构造及析构
2.string类的遍历
3.string类的插入和删除
4.string类的空间处理
5.string类的查找
6.string类的输出和输入
7.string类的常用判断
二.整体代码
1.string.h
2.string.cpp 一.实现string类
在前一节中我们了解了STL中string的部分接口,在这里我们实现一个自己的string类
当我们实现自己的string类时,名字会与库内的冲突,所以可以选择用命名空间解决
1.string的构造及析构
当我们在开空间的时候一般要多开一个用于存放\0
拷贝构造和赋值用传统方法写一般是开新空间,复制过去,释放旧空间,但是在这里我们使用现代写法,直接将空间交换过来使用
而在swap函数中使用::,是为了让他去调用库中的函数,而不是类中的
string(const char* str )
{_size strlen(str);_capacity _size;_str new char[_capacity 1];//strcpy(_str,str);不安全,会报错,无法实现功能,在后面主要使用strcpy_sstrcpy_s(_str, strlen(str) 1, str);//c11标准
}//深拷贝,若用编译器自动生成的为浅拷贝,析构时会出现问题
string(const string s):_str(nullptr),_size(0),_capacity(0)
{string tmp(s._str);//his-swap(tmp);swap(tmp);
}void swap(string s)
{::swap(_str, s._str);::swap(_size, s._size);::swap(_capacity, s._capacity);
}~string()
{delete[] _str;_str nullptr;_size _capacity 0;
}string operator(string s)
{//this-swap(s);swap(s);return *this;
}
2.string类的遍历
对于string类的遍历我们可以通过[]下标,迭代器,范围for语句遍历,以及c_str
所以我们需要自己定义迭代器,重载[]
typedef char* iterator;iterator begin()
{return _str;
}iterator end()
{return _str _size;
}char operator[](size_t i)
{assert(i _size);return _str[i];
}const char operator[](size_t i) const
{assert(i _size);return _str[i];
}const char* c_str()
{return _str;
}
3.string类的插入和删除
对于插入我们都要考虑的便是容量不够需要增容,同时也应该考虑字符串开始为空的情况,如果为空就给一个容量,否则就扩2倍
push_back的话我们只需要将字符加在末端即可
append将插入的字符串复制到原字符串末尾即可
对于单个push_back,字符串复用append
insert插入单个字符时,将字符从末尾开始向后移一位,将字符插入头即可,插入字符串时后移的位数变为插入字符串的长度
erase删除主要考虑两种情况,删除一部分和全部删完,全部删完比较简单,将删除的位置变为\0,将size变为pos即可,删除部分,将后面的字符前移覆盖
void push_back(char ch){if (_size _capacity){size_t newcapacity _capacity 0 ? 2 : _capacity * 2;reserve(newcapacity);}_str[_size] ch;_size;_str[_size] \0;}void append(const char* str){size_t len strlen(str);if (_size len _capacity){reserve(_size len);}//strcpy(_str _size, str);strcpy_s(_str _size, strlen(str) 1, str);_size len;}string operator(char ch){this-push_back(ch);return *this;}string operator(const char* str){this-append(str);return *this;}string insert(size_t pos, char ch){assert(pos _size);if (_size _capacity){size_t newcapacity _capacity 0 ? 2 : _capacity * 2;reserve(newcapacity);}int end _size;while (end (int)pos){_str[end 1] _str[end];--end;}_str[pos] ch;_size;return *this;}string insert(size_t pos, const char* str){assert(pos _size);size_t len strlen(str);if (_size len _capacity){reserve(_size len);}int end _size;while (end (int)pos){_str[end len] _str[end];--end;}for (size_t i 0; i len; i){_str[pos] str[i];}_size len;return *this;}void erase(size_t pos, size_t len npos){assert(pos _size);if (len _size - pos){_str[pos] \0;_size pos;}else{size_t i pos len;while (i _size){_str[i - len] _str[i];i;}_size - len;}}
4.string类的空间处理
reserve比较简单,直接开出一段空间即可,而resize则需要考虑空间的缩小,缩小的话将给定位置变为\0,放大空间的话,reserve空间,然后将size后面的都填上给定的或默认字符 size_t size() const{return _size;}size_t capacity() const{return _capacity;}void reserve(size_t n){if (n _capacity){char* tmp new char[n 1];//strcpy(tmp, _str);strcpy_s(tmp, strlen(_str) 1, _str);delete[] _str;_str tmp;_capacity n;}}void resize(size_t n, char ch \0){if (n _size){_str[n] \0;_size n;}else{if (n _capacity){reserve(n);}for (size_t i _size; i n; i){_str[i] ch;}_size n;_str[_size] \0;}}
5.string类的查找
size_t find(char ch, size_t pos 0)
{for (size_t i pos; i _size; i){if (_str[i] ch){return i;}}return npos;
}size_t find(const char* str, size_t pos 0)
{char* p strstr(_str, str);if (p nullptr){return npos;}else{return p - _str;}
}
6.string类的输出和输入 ostream operator(ostream out, const string s){for (size_t i 0; i s.size(); i){cout s[i];}return out;}//getline()只需要去掉if中的 即可istream operator(istream in, string s){while (1){char ch;ch in.get();if (ch || ch \n){break;}else{s ch;}}return in;}
7.string类的常用判断
bool operator(const string s)
{int ret strcmp(_str, s._str);return ret 0;
}bool operator(const string s)
{int ret strcmp(_str, s._str);return ret 0;
}bool operator(const string s)
{return *this s || *this s;
}bool operator(const string s)
{return !(*this s);
}bool operator(const string s)
{return !(*this s);
}bool operator!(const string s)
{return !(*this s);
}
二.整体代码
1.string.h
#pragma once
#includeiostream
#includeassert.h
using namespace std;
namespace wzyl
{class string{public:typedef char* iterator;iterator begin(){return _str;}iterator end(){return _str _size;}string(const char* str ){_size strlen(str);_capacity _size;_str new char[_capacity 1];//strcpy(_str,str);不安全,会报错,无法实现功能,在后面主要使用strcpy_sstrcpy_s(_str, strlen(str) 1, str);//c11标准}//深拷贝,若用编译器自动生成的为浅拷贝,析构时会出现问题string(const string s):_str(nullptr),_size(0),_capacity(0){string tmp(s._str);//his-swap(tmp);swap(tmp);}void swap(string s){::swap(_str, s._str);::swap(_size, s._size);::swap(_capacity, s._capacity);}~string(){delete[] _str;_str nullptr;_size _capacity 0;}string operator(string s){//this-swap(s);swap(s);return *this;}size_t size() const{return _size;}size_t capacity() const{return _capacity;}char operator[](size_t i){assert(i _size);return _str[i];}const char operator[](size_t i) const{assert(i _size);return _str[i];}const char* c_str(){return _str;}void reserve(size_t n){if (n _capacity){char* tmp new char[n 1];//strcpy(tmp, _str);strcpy_s(tmp, strlen(_str) 1, _str);delete[] _str;_str tmp;_capacity n;}}void resize(size_t n, char ch \0){if (n _size){_str[n] \0;_size n;}else{if (n _capacity){reserve(n);}for (size_t i _size; i n; i){_str[i] ch;}_size n;_str[_size] \0;}}void push_back(char ch){if (_size _capacity){size_t newcapacity _capacity 0 ? 2 : _capacity * 2;reserve(newcapacity);}_str[_size] ch;_size;_str[_size] \0;}void append(const char* str){size_t len strlen(str);if (_size len _capacity){reserve(_size len);}//strcpy(_str _size, str);strcpy_s(_str _size, strlen(str) 1, str);_size len;}string operator(char ch){this-push_back(ch);return *this;}string operator(const char* str){this-append(str);return *this;}string insert(size_t pos, char ch){assert(pos _size);if (_size _capacity){size_t newcapacity _capacity 0 ? 2 : _capacity * 2;reserve(newcapacity);}int end _size;while (end (int)pos){_str[end 1] _str[end];--end;}_str[pos] ch;_size;return *this;}string insert(size_t pos, const char* str){assert(pos _size);size_t len strlen(str);if (_size len _capacity){reserve(_size len);}int end _size;while (end (int)pos){_str[end len] _str[end];--end;}for (size_t i 0; i len; i){_str[pos] str[i];}_size len;return *this;}void erase(size_t pos, size_t len npos){assert(pos _size);if (len _size - pos){_str[pos] \0;_size pos;}else{size_t i pos len;while (i _size){_str[i - len] _str[i];i;}_size - len;}}size_t find(char ch, size_t pos 0){for (size_t i pos; i _size; i){if (_str[i] ch){return i;}}return npos;}size_t find(const char* str, size_t pos 0){char* p strstr(_str, str);if (p nullptr){return npos;}else{return p - _str;}}bool operator(const string s){int ret strcmp(_str, s._str);return ret 0;}bool operator(const string s){int ret strcmp(_str, s._str);return ret 0;}bool operator(const string s){return *this s || *this s;}bool operator(const string s){return !(*this s);}bool operator(const string s){return !(*this s);}bool operator!(const string s){return !(*this s);}private:char* _str;size_t _size;//有效字符个数size_t _capacity;//能存多少有效字符,\0不是有效字符static size_t npos;};size_t string::npos -1;ostream operator(ostream out, const string s){for (size_t i 0; i s.size(); i){cout s[i];}return out;}//getline()只需要去掉if中的 即可istream operator(istream in, string s){while (1){char ch;ch in.get();if (ch || ch \n){break;}else{s ch;}}return in;}void test_string1(){string s1(hello);string s2;cout s1 endl;cout s2 endl;cout s1.c_str() endl;cout s2.c_str() endl;//3种遍历方式for (size_t i 0; i s1.size(); i){s1[i] 1;cout s1[i] ;}cout endl;string::iterator it s1.begin();while (it ! s1.end()){*it - 1;cout *it ;it;}cout endl;//范围for是由迭代器支持的,所以这段代码最后会被替换成迭代器for (auto e : s1){cout e ;}cout endl;}void test_string2(){string s1(hello);s1.push_back( );s1.push_back(w);s1.push_back(o);s1.push_back(r);s1.push_back(l);s1.push_back(d);cout s1 endl;s1.append(xxxxxxxxx);cout s1 endl;string s2;s2 hello;s2 ;s2 world;cout s2 endl;}void test_string3(){string s1(hello);s1.insert(1, x);s1.insert(1, xyz);s1.insert(0, p);cout s1 endl endl;string s2(hello);s2.reserve(10);cout s2 endl;cout s2.size() endl;cout s2.capacity() endl endl;s2.resize(10, x);cout s2 endl;cout s2.size() endl;cout s2.capacity() endl endl;s2.resize(18, a);cout s2 endl;cout s2.size() endl;cout s2.capacity() endl endl;s2.resize(2);cout s2 endl;cout s2.size() endl;cout s2.capacity() endl;}void test_string4(){string s(helloworld);s.erase(5, 2);cout s endl;s.erase(5, 4);cout s endl;string s1(abcdabcdef);cout s1.find(cde) endl;cout s1.find(fgh) endl;}void test_string5(){string s;cin s;cout s endl;string s1(s);cout s1 endl;string s2 s1;cout s2 endl;}
}
2.string.cpp
#include string.hint main()
{wzyl::test_string1();wzyl::test_string2();wzyl::test_string3();wzyl::test_string4();wzyl::test_string5();return 0;
}