以下就是String類的模擬實現:
測試環境爲VS2013
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
class String
{
private:
friend ostream& operator<<(ostream& _cout, const String& s);
char* _str;
size_t _size;
size_t _capacity;
public:
static const size_t npos;
typedef char* iterator;
typedef const char* const_iterator;
//構造函數
String(char* str = "")
:_str(new char[strlen(str+1)])
{
assert(str != nullptr);
_size = strlen(str);
_str = new char[_size + 1];
strcpy(_str, str); //包括'\0'
_capacity = _size;
}
//拷貝構造函數
String(const String& s)
:_str(new char[strlen(s._str + 1)])
{
strcpy(_str, s._str);
}
//賦值運算符重載
String& operator= (const String&s)
{
//先判斷是否給自己賦值
if (this != &s)
{
delete[] _str;
_str = nullptr;
_str = new char[strlen(s._str + 1)];
strcpy(_str, s._str);
}
return *this;
}
//operator[]重載,可讀可寫接口
char& operator[](size_t pos)
{
assert(pos < _size);
return _str[pos];
}
//const接口
const char& operator[](size_t pos) const
{
assert(pos < _size);
return _str[pos];
}
//迭代器
iterator begin()
{
return _str;
}
iterator end()
{
return (_str + _size);
}
const iterator begin() const
{
return _str;
}
const iterator end() const
{
return (_str + _size);
}
size_t Size() const
{
return _size;
}
//析構函數
~String()
{
if (_str)
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
}
const char* c_str() const
{
return _str;
}
//只增容,不減少容量,拷貝原有內容,釋放原有空間
void Reserve(size_t n)
{
if (n > _capacity)
{
char* tmp = new char[n + 1];
strcpy(tmp, _str);
//釋放原有空間
delete _str;
//指向新的空間
_str = tmp;
//更新容量
_capacity = n;
}
}
//尾插
void PushBack(char c)
{
//驗容
if (_size == _capacity)
{
size_t newC = (_capacity == 0 ? 15 : 2 * _capacity);
Reserve(newC);
}
_str[_size] = c;
_size++;
_str[_size] = '\0';
}
//尾刪
void PopBack()
{
if (_size > 0)
{
_size--;
_str[_size] = '\0';
}
}
void Resize(size_t n, char c)
{
if (n > _capacity)
{
Reserve(n);
}
if (n > _size)
// _size < n <= _capacity
{
//按字節複製
memset(_str + _size, c, n - _size);
}
_size = n;
_str[_size] = '\0';
}
//刪除
void Erase(size_t pos, size_t len)
{
//刪除的位置要合法
assert(pos < _size);
if (pos + len >= _size)
{
_size = pos;
_str[_size] = '\0';
}
else
{
//從pos+len開始向前每次移動len 個字符
for (size_t i = pos + len; i <= _size; i++)
{
_str[pos] = _str[i];
pos++;
}
_size -= len;
}
}
//追加
void Append(const char* str)
{
size_t sz = strlen(str);
if (_size + sz > _capacity)
{
Reserve(_size + sz);
}
strcpy(_str + _size, str);
_size += sz;
}
//插入字符
void Insert(size_t pos, char c)
{
assert(pos <= _size);
//增容
if (_size == _capacity)
{
size_t newCapacity = (_capacity == 0 ? 15 : 2 * _capacity);
Reserve(newCapacity);
}
//元素依次向後移動,留出位置
size_t end = _size;
for (size_t i = end; i >= pos; i--)
{
_str[i] = _str[i - 1];
}
_str[pos] = c;
_size++;
_str[_size] = '\0';
}
//插入字符串
void Insert(size_t pos, const char* str)
{
assert(pos <= _size);
size_t len = strlen(str);
//因爲要插入字符串,字符串的長度不確定,可短可長,所以增容不能只單單地增加2倍
if (_size + len > _capacity)
{
Reserve(_size + len);
}
size_t end = _size + len;
while (end > pos+len-1)
{
_str[end] = _str[end - len];
--end;
}
while (*str)
{
_str[pos] = *str;
pos++;
str++;
}
_size += len;
}
//查找字符
size_t Find_Ch(char c)
{
for (size_t i = 0; i < _size; i++)
{
if (_str[i] == c)
{
return i;
}
}
return npos;
//return -1;
}
//查找字符串
size_t Find_Str(size_t pos, char* str)
{
char* posPtr = strstr(_str + pos, str);
if (posPtr)
{
return posPtr - _str;
}
else
return npos;
}
String& operator+=(char c)
{
PushBack(c);
return *this;
}
String& operator+=(const char* str)
{
Append(str);
return *this;
}
String& operator+=(const String&s)
{
Append(s._str);
return *this;
}
};
const size_t String::npos = -1;
//輸出運算符重載
ostream& operator<<(ostream& _cout, const String&s)
{
_cout << s.c_str() << endl;
return _cout;
}
//普通打印
void Print_String(const String&s)
{
for (size_t i = 0; i < s.Size(); i++)
{
//s.operator[](&s, i);
cout << s[i];
}
cout << endl;
}
//用迭代器來打印
void Print_String_Iterator(const String& s)
{
String :: const_iterator sit = s.begin();
while (sit != s.end())
{
cout << *sit;
++sit;
}
cout << endl;
}
void Test1()
{
String s1;
//String s1("hello");
//Print_String(s1);
//cout << s1.Size() << endl;
s1.PushBack('h');
s1.PushBack('e');
s1.PushBack('l');
s1.PushBack('l');
s1.PushBack('o');
s1.PushBack(' ');
s1.PushBack('C');
s1.PushBack('+');
s1.PushBack('+');
s1.PushBack('!');
Print_String(s1); //hello C++!
//修改一個值
s1[0] = 'H';
Print_String(s1); //Hello C++!
//尾刪
s1.PopBack();
Print_String(s1); //Hello C++
//測試Resize()
s1.Resize(12, '!');
Print_String(s1); //Hello C++!!!
//測試Erase()
s1.Erase(10, 2);
Print_String(s1);//Hello C++!
//測試Append()
s1.Append("!!!!");
Print_String(s1);// Hello C++!!!!!
//測試Insert()
s1.Insert(5, '!');
Print_String(s1);//Hello! C++!!!!!
//測試Insert()字符串
s1.Insert(6, " I Love");
Print_String(s1);
//測試Find_Ch
size_t ret = 0;
ret = s1.Find_Ch('C');
cout << "查找C" << endl << "查找結果:";
cout << ret << endl; //14
//測試Find_Str()
cout << "查找子串:C++" << endl;
cout << s1.Find_Str(13, "C++") << endl;
//測試迭代器打印
cout << "用迭代器來打印:";
Print_String_Iterator(s1);
//測試operator+=(char)
cout << "測試operator+= (char)";
s1.operator+=('~');
Print_String(s1);
//測試operator+=(str)
cout << "測試operator+= (str) ";
s1.operator+=("~~~");
Print_String(s1);
//測試operator+=(String&s)
String s2("Happy");
cout << "測試operator+= (String&s) ";
s1.operator+=(s2);
Print_String(s1);
}
int main()
{
Test1();
system("pause");
return 0;
}