#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<assert.h>
namespace weige {
class String
{
public:
typedef char* iterator;
String(const char* str = "")
{
if (nullptr == str)
{
str = "";
}
_str = new char[strlen(str) + 1];
strcpy(_str, str);
_size = strlen(str);
_capacity = _size;
}
String(int n, char ch)
{
_str = new char[n + 1];
memset(_str, ch, n);
_size = n;
_capacity = n;
_str[_size] = '\0';
}
String(const String& s)
: _str(nullptr)
{
String temp(s._str);
this->swap(temp);
}
String& operator=(String s)
{
this->swap(s);
return *this;
}
void swap(String& s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
~String()
{
if (_str)
{
delete[] _str;
_str = nullptr;
_size = 0;
_capacity = 0;
}
}
size_t size() const
{
return _size;
}
size_t length()const
{
return _size;
}
size_t capacity()const
{
return _capacity;
}
char& operator[] (size_t pos)
{
if (pos >= _size)
assert(0);
return _str[pos];
}
const char& operator[] (size_t pos) const
{
if (pos >= _size)
assert(0);
return _str[pos];
}
char& at(size_t pos)
{
return _str[pos];
}
const char& at(size_t pos)const
{
return _str[pos];
}
void clear()
{
_size = 0;
}
bool empty()const
{
return 0 == _size;
}
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
void resize(size_t n)
{
resize(n, '\0');
}
void resize(size_t newsize, char val)
{
size_t oldsize = _size;
if (newsize > capacity())
reserve(newsize);
memset(_str + _size, val, newsize - oldsize);
_size = newsize;
_str[_size] = '\0';
}
void reserve(size_t newcapacity = 0)
{
size_t oldcapacity = capacity();
if (newcapacity > oldcapacity)
{
char* temp = new char[newcapacity + 1];
strncpy(temp, _str, _size);
delete[] _str;
_str = temp;
_capacity = newcapacity;
_str[_size] = '\0';
}
}
void push_back(char c)
{
*this += c;
}
void pop_back()
{
_size -= 1;
}
String& operator+=(const String& s)
{
*this += s.c_str();
return *this;
}
const char* c_str()const
{
return _str;
}
String& operator+=(const char* str)
{
size_t newsize = _size + strlen(str);
size_t leavesize = _capacity - _size;
if (leavesize < newsize)
reserve(newsize + 1);
strcat(_str, str);
_str[newsize] = '\0';
_size = newsize;
_capacity = newsize + 1;
return *this;
}
String& operator+=(char ch)
{
if (_size == _capacity)
reserve((size_t)_capacity * 1.5 + 3);
_str[_size] = ch;
_str[_size + 1] = '\0';
_size = _size + 1;
return *this;
}
String& append(const String& str)
{
*this += str.c_str();
return *this;
}
String& append(const char* str)
{
*this += str;
return *this;
}
String& append(size_t n, char ch)
{
for (size_t i = 0; i < n; i++)
*this += ch;
return *this;
}
String& erase(size_t pos = 0, size_t len = npos)
{
if (pos + len >= _size)
{
_size = pos;
_str[_size] = '\0';
}
else
{
size_t start = pos+len;
strcpy(_str + pos, _str + start);
_size -= len;
}
return *this;
}
size_t find(const string& str, size_t pos = 0) const
{
return find(str.c_str());
}
size_t find(const char* s, size_t pos = 0) const
{
if (pos >= _size)
{
return npos;
}
char* res;
res = strstr(_str, s);
if (res == nullptr)
return npos;
else
return res - _str; // 相对于首部的偏移量
}
//通用Insert接口
void Insert(size_t pos, char ch) {
assert(pos <= _size);
if (_size == _capacity) {
reserve(_capacity * 2);
}
for (size_t i = _size; i >= pos; --i) { //从'\0'开始挪动数据
_str[i + 1] = _str[i];
}
_str[pos] = ch;
_size++;
}
void Insert(size_t pos, const char* str) {
assert(pos <= _size);
size_t len = strlen(str);
if (_size + len > _capacity) {
reserve(_size + len);
}
for (size_t i = _size; i >= pos; --i) {
_str[i + len] = _str[i];
}
strncpy(_str + pos, str, len);
_size += len;
}
size_t find(char c, size_t pos = 0) const
{
if (pos >= _size)
{
return npos;
}
else
{
for (size_t i = pos; i < _size; ++i)
{
if (c == _str[i])
return i;
}
return npos;
}
}
String substr(size_t pos = 0, size_t len = npos) const
{
if (pos >= _size)
return String();
len = min(len, _size - pos);
String temp(len, '\0');
size_t index = 0;
for (size_t i = pos; i < pos + len; i++)
temp[index++] = _str[i];
return temp;
}
private:
char* _str;
size_t _size;
size_t _capacity;
const static size_t npos = -1;
friend ostream& operator<<(ostream& out, const String& s);
};
ostream& operator<<(ostream& out, const String& s)
{
for (size_t i = 0; i < s.size(); i++)
{
cout << s[i];
}
cout << endl;
return out;
}
}
void Test01()
{
weige::String s1("hello");
weige::String s2(s1);
}
void Test02()
{
weige::String s1("hello world");
weige::String s2;
s2 = s1;
cout << s1 << endl;
}
void Test03()
{
weige::String s1("hello world");
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('a');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('b');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('c');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('d');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('e');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('f');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('g');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('h');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
}
void Test04()
{
weige::String s1("hello world");
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.push_back('a');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1 += ('b');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1 += ('c');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1 += ('d');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1 += ('e');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1 += ('f');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1 += ('g');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1 += ('h');
cout << s1.size() << endl;
cout << s1.capacity() << endl;
}
void Test05()
{
weige::String s1("hello world");
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1 += "abc";
cout << s1 << endl;
const char* temp = "aaaaa";
s1 += temp;
cout << s1 << endl;
}
void Test06()
{
weige::String s1("hello world");
weige::String s2("hello");
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.append(10, ' ');
cout << s1 << endl;
s1.append("abcdef");
cout << s1 << endl;
s1.append(s2);
cout << s1 << endl;
}
void Test07()
{
weige::String s1("hello world");
weige::String s2;
size_t pos = s1.find(' ');
s2 = s1.substr(pos + 1);
cout << s1 << endl << s2 << endl;
}
void Test08()
{
weige::String s1("hello world");
weige::String s2(s1);
s1.erase(0);
s2.erase(5, 5);
cout << s1 << endl << s2 << endl;
}
int main()
{
// Test01();
// Test02();
// Test03();
// Test04();
// Test05();
// Test06();
// Test07();
Test08();
return 0;
}
(十四)String类底层代码剖析
于 2022-12-29 17:22:48 首次发布