本篇主要介绍模拟实现string类,string中有相当多的内容,这里实现一些相对用途广泛的场景
先看要实现的内容有哪些:
上图源于cplusplus网站,从中截取了部分内容准备进行模拟实现
首先既然string是一个类,那么首先要把类的这个框架搭建起来,我们把string类这个对象放到命名空间中,这样就不会和std中的类所冲突,一个类起码要有构造函数析构函数成员变量:
namespace My_string { class string { public: // Constructor/Destructor string(const char* str = "") : _size(strlen(str)) , _capacity(_size) { _str = new char[_capacity + 1]; strcpy(_str, str); } ~string() { delete[] _str; } string& operator=(const char* str) { _size = strlen(str); _capacity = _size; _str = new char[_capacity + 1]; strcpy(_str, str); return *this; } string& operator=(const string& str) { _capacity = str._capacity; _size = str._size; _str = new char[_capacity + 1]; strcpy(_str, str._str); return *this; } string& operator=(char c) { _capacity = 1; _size = 1; _str = new char[_capacity + 1]; _str[0] = c; return *this; } private: char* _str; size_t _size; size_t _capacity; const static size_t npos; }; const size_t string::npos = -1; }
至此,string类的大体框架已经搭建完毕了,下面进行string类内部成员函数的完善
Iterator类
begin和end迭代器实现:
从上面库函数中可以看出,这里返回的是迭代器,而我们又知道,实际上迭代器就是指针的作用,因此我们这里就用指针来模拟实现迭代器的作用
// Iterator typedef char* iterator; typedef const char* const_iterator; iterator begin() { return _str; } const_iterator begin() const { return _str; } iterator end() { return _str + _size; } const_iterator end() const { return _str + _size; }
capacity类
实现的函数主要有:
// Capacity size_t size() { return _size; } size_t size() const { return _size; } size_t lenth() { return _size; } void resize(size_t n, char c = '\0') { ; } size_t capacity() { return _capacity; } void reserve(size_t n) { if (n > _capacity) { char* tmp = new char[n + 1]; strcpy(tmp, _str); delete[] _str; _str = tmp; _capacity = n; } } void clear() { memset(_str, '\0', _size); _size = 0; } bool empty() const { if (_size == 0) { return true; } return false; }
Element access 类
实现的函数主要有
// Element access char& operator[](size_t pos) { assert(pos < _size); return _str[pos]; } const char& operator[](size_t pos) const { assert(pos < _size); return _str[pos]; } char& at(size_t pos) { assert(pos < _size); return _str[pos]; } const char& at(size_t pos) const { assert(pos < _size); return _str[pos]; } char& back() { return _str[_size - 1]; } const char& back() const { assert(_size - 1 >= 0); return _str[_size - 1]; } char& front() { assert(_size - 1 >= 0); return _str[0]; } const char& front() const { return _str[0]; }
Modifiers类
实现的函数主要有
//Modifiers string operator+(const char* str) { size_t len = strlen(str); reserve(len + _size); strcpy(_str + _size, str); string s1; s1 = *this; return s1; } string operator + (const string& str) { size_t len = strlen(str._str); reserve(len + _size); strcpy(_str + _size, str._str); string s1; s1 = *this; return s1; } string operator + (char str) { if (_size == _capacity) { reserve(_size + 1); } _str[_size++] = str; string s1; s1 = *this; return s1; } string& operator+=(const char* str) { append(str); return *this; } string& operator += (const string& str) { append(str); return *this; } string& operator += (char str) { push_back(str); return *this; } void append(const string& str) { size_t len = strlen(str._str); if (_size + len > _capacity) { reserve(_size + len); } strcpy(_str + _size, str._str); _size += len; } void append(const char* str) { size_t len = strlen(str); if (_size + len > _capacity) { reserve(_size + len); } strcpy(_str + _size, str); _size += len; } void push_back(char c) { if (_size == _capacity) { reserve(_capacity == 0 ? 4 : _capacity * 2); } _str[_size++] = c; _str[_size] = '\0'; } string& insert(size_t pos, char ch) { assert(pos <= _size); if (_size == _capacity) { reserve(_capacity == 0 ? 4 : _capacity * 2); } size_t end = _size + 1; while (end > pos) { _str[end] = _str[end - 1]; --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(_capacity == 0 ? 4 : _capacity * 2); } size_t end = _size + len; while (end > pos + len - 1) { _str[end] = _str[end - len]; --end; } memmove(_str + pos, str, len); _size += len; } string& insert(size_t pos, const string& str) { assert(pos <= _size); size_t len = strlen(str._str); if (_size + len == _capacity) { reserve(_capacity == 0 ? 4 : _capacity * 2); } size_t end = _size + len; while (end > pos + len - 1) { _str[end] = _str[end - len]; --end; } memmove(_str + pos, str._str, len); _size += len; } string& erase(size_t pos, size_t len = npos) { if (len == -1) { size_t n = pos; while (n < _size) { _str[n] = '\0'; n++; } _size = pos - 1; } else { assert(pos + len < _size); size_t left = pos + len - 1; size_t end = _size + 1; while (left < end) { _str[pos] = _str[left]; pos++; left++; } _size = _size - len; } return *this; } void swap(string& s) { string tmp = s; s = *this; *this = tmp; } void pop_back() { _str[_size - 1] = '\0'; _size--; }
String operations类
实现的函数主要有:
char* c_str() { return _str; } size_t find(const string& str, size_t pos = 0) const { int begin = 0; int end = (int)_size; while (begin < end) { size_t len = strlen(str._str); if (_str[begin] == str._str[0]) { int left = begin; int res = 1; for (int i = 0; i < len; i++) { if (_str[left] != _str[i]) { break; } res++; left++; } if (res == len) { return begin; } } else { begin++; } } return npos; } string substr(size_t pos = 0, size_t len = npos) const { string s1; if (len == npos) { while (_str[pos] != '\0') { s1 += _str[pos]; pos++; } } else { for (int i = 0; i < len; i++) { s1 += _str[pos]; pos++; } } return s1; } string operator+ (const string& str) const { return *this + str; } bool operator== (const string& str) const { return strcmp(_str, str._str) == 0; } bool operator!= (const string& str) const { return !(*this == str); } bool operator< (const string& str) const { return strcmp(_str, str._str) < 0; } bool operator> (const string& str) const { return strcmp(_str, str._str) > 0; } bool operator<= (const string& str) const { return (*this < str) || (*this == str); } bool operator>= (const string& str) const { return (*this > str) || (*this == str); }
类外成员函数
实现的函数主要有:
std::ostream& operator<<(std::ostream& out, const string& s) { for (size_t i = 0; i < s.size(); i++) { out << s[i]; } return out; } std::istream& operator>>(std::istream& in, string& s) { s.clear(); char ch; ch = in.get(); s.reserve(128); while (ch != ' ' && ch != '\n') { s += ch; ch = in.get(); } return in; }
头文件总括
#include <iostream> #include <assert.h> namespace My_string { typedef char* iterator; typedef const char* const_iterator; class string { public: // Constructor/Destructor string(const char* str = "") : _size(strlen(str)) , _capacity(_size) { _str = new char[_capacity + 1]; strcpy(_str, str); } ~string() { delete[] _str; } string& operator=(const char* str) { _size = strlen(str); _capacity = _size; _str = new char[_capacity + 1]; strcpy(_str, str); return *this; } string& operator=(const string& str) { _capacity = str._capacity; _size = str._size; _str = new char[_capacity + 1]; strcpy(_str, str._str); return *this; } string& operator=(char c) { _capacity = 1; _size = 1; _str = new char[_capacity + 1]; _str[0] = c; return *this; } // Iterator iterator begin() { return _str; } const_iterator begin() const { return _str; } iterator end() { return _str + _size; } const_iterator end() const { return _str + _size; } // Capacity size_t size() { return _size; } size_t size() const { return _size; } size_t lenth() { return _size; } void resize(size_t n, char c = '\0') { ; } size_t capacity() { return _capacity; } void reserve(size_t n) { if (n > _capacity) { char* tmp = new char[n + 1]; strcpy(tmp, _str); delete[] _str; _str = tmp; _capacity = n; } } void clear() { memset(_str, '\0', _size); _size = 0; } bool empty() const { if (_size == 0) { return true; } return false; } // Element access char& operator[](size_t pos) { assert(pos < _size); return _str[pos]; } const char& operator[](size_t pos) const { assert(pos < _size); return _str[pos]; } char& at(size_t pos) { assert(pos < _size); return _str[pos]; } const char& at(size_t pos) const { assert(pos < _size); return _str[pos]; } char& back() { return _str[_size - 1]; } const char& back() const { assert(_size - 1 >= 0); return _str[_size - 1]; } char& front() { assert(_size - 1 >= 0); return _str[0]; } const char& front() const { return _str[0]; } //Modifiers string operator+(const char* str) { size_t len = strlen(str); reserve(len + _size); strcpy(_str + _size, str); string s1; s1 = *this; return s1; } string operator + (const string& str) { size_t len = strlen(str._str); reserve(len + _size); strcpy(_str + _size, str._str); string s1; s1 = *this; return s1; } string operator + (char str) { if (_size == _capacity) { reserve(_size + 1); } _str[_size++] = str; string s1; s1 = *this; return s1; } string& operator+=(const char* str) { append(str); return *this; } string& operator += (const string& str) { append(str); return *this; } string& operator += (char str) { push_back(str); return *this; } void append(const string& str) { size_t len = strlen(str._str); if (_size + len > _capacity) { reserve(_size + len); } strcpy(_str + _size, str._str); _size += len; } void append(const char* str) { size_t len = strlen(str); if (_size + len > _capacity) { reserve(_size + len); } strcpy(_str + _size, str); _size += len; } void push_back(char c) { if (_size == _capacity) { reserve(_capacity == 0 ? 4 : _capacity * 2); } _str[_size++] = c; _str[_size] = '\0'; } string& insert(size_t pos, char ch) { assert(pos <= _size); if (_size == _capacity) { reserve(_capacity == 0 ? 4 : _capacity * 2); } size_t end = _size + 1; while (end > pos) { _str[end] = _str[end - 1]; --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(_capacity == 0 ? 4 : _capacity * 2); } size_t end = _size + len; while (end > pos + len - 1) { _str[end] = _str[end - len]; --end; } memmove(_str + pos, str, len); _size += len; } string& insert(size_t pos, const string& str) { assert(pos <= _size); size_t len = strlen(str._str); if (_size + len == _capacity) { reserve(_capacity == 0 ? 4 : _capacity * 2); } size_t end = _size + len; while (end > pos + len - 1) { _str[end] = _str[end - len]; --end; } memmove(_str + pos, str._str, len); _size += len; } string& erase(size_t pos, size_t len = npos) { if (len == -1) { size_t n = pos; while (n < _size) { _str[n] = '\0'; n++; } _size = pos - 1; } else { assert(pos + len < _size); size_t left = pos + len - 1; size_t end = _size + 1; while (left < end) { _str[pos] = _str[left]; pos++; left++; } _size = _size - len; } return *this; } void swap(string& s) { string tmp = s; s = *this; *this = tmp; } void pop_back() { _str[_size - 1] = '\0'; _size--; } // String operations char* c_str() { return _str; } size_t find(const string& str, size_t pos = 0) const { int begin = 0; int end = (int)_size; while (begin < end) { size_t len = strlen(str._str); if (_str[begin] == str._str[0]) { int left = begin; int res = 1; for (int i = 0; i < len; i++) { if (_str[left] != _str[i]) { break; } res++; left++; } if (res == len) { return begin; } } else { begin++; } } return npos; } string substr(size_t pos = 0, size_t len = npos) const { string s1; if (len == npos) { while (_str[pos] != '\0') { s1 += _str[pos]; pos++; } } else { for (int i = 0; i < len; i++) { s1 += _str[pos]; pos++; } } return s1; } string operator+ (const string& str) const { return *this + str; } bool operator== (const string& str) const { return strcmp(_str, str._str) == 0; } bool operator!= (const string& str) const { return !(*this == str); } bool operator< (const string& str) const { return strcmp(_str, str._str) < 0; } bool operator> (const string& str) const { return strcmp(_str, str._str) > 0; } bool operator<= (const string& str) const { return (*this < str) || (*this == str); } bool operator>= (const string& str) const { return (*this > str) || (*this == str); } private: char* _str; size_t _size; size_t _capacity; const static size_t npos; }; const size_t string::npos = -1; std::ostream& operator<<(std::ostream& out, const string& s) { for (size_t i = 0; i < s.size(); i++) { out << s[i]; } return out; } std::istream& operator>>(std::istream& in, string& s) { s.clear(); char ch; ch = in.get(); s.reserve(128); while (ch != ' ' && ch != '\n') { s += ch; ch = in.get(); } return in; } }