一、string类的成员变量
class string
{
private:
char* _str;
size_t _capacity;
size_t _size;
};
二、四大默认成员函数的实现
(1)构造函数
string(const char* s = "")
:_size(strlen(s))
, _capacity(_size)
, _str(new char[_capacity + 1])
{
strcpy(_str, s);
}
(2)拷贝构造函数
string类再拷贝构造的时候,指针不能进行浅拷贝,而是需要深拷贝 | |
---|
string(const string& s)
:_str(new char[strlen(s._str)+1])
{
strcpy(_str, s._str);
_size = s._size;
_capcacity = s._capacity;
}
(3)析构函数
string类的析构函数还是很有必要的,因为有动态开辟空间需要清理 | |
---|
~string()
{
delete[] _str;
_str = nullptr;
_size = 0;
_capacity = 0;
}
(4)赋值运算符重载
string& operator&=(string s)
{
if(this != &s)
{
delete[] _str;
_str = new char[strlen(s._str)+1];
strcpy(_str, s._str);
_size = s._size;
_capacity = s._capacity;
}
}
三、string类中辅助功能实现

(1)reserve
开辟空间,扩展_capacity,但是_str、_size不变 | |
---|
void reverse(size_t n)
{
if(n>_capacity)
{
char* tmp = new char[n+1];
strncpy(tmp, _str, _size+1);
delete[] _str;
_str = tmp;
_capacity = n;
}
}
(2)resize
不是开辟空间,而是扩展_size,并且将_str中存储相应字符(默认’\0’) | |
---|
void resize(size_t n, char ch = '\0')
{
if(n>_size)
{
if(n>_capacity)
{
reverse(n);
}
memset(_str+_size, ch, n-_size);
}
_size = n;
_str[_size] = '\0';
}
(3)size
const size_t size()
{
return _size;
}
(4)clear
void clear()
{
_size = 0;
_str[0] = '\0';
}
(5)empty
bool empty()
{
return _size == 0;
}
四、string的增删查改

(1)push_back
void push_back(char ch)
{
if(_size == _capacity)
{
reverse(_capacity == 0? 4:2*_capacity);
}
_str[_size++] = ch;
_str[_size] = '\0';
}
(2)append
void append(const char* s)
{
size_t len = _size + strlen(s);
if(len > _capacity)
{
reverse(len);
}
strcpy(_str+_size, s);
_size = len;
}
(3)operator+=
string& operator+=(char ch)
{
push_back(ch);
return *this;
}
string& operator+=(const char* s)
{
append(s);
return *this;
}
(4)insert
string& insert(szie_t pos = 0, char ch)
{
assert(pos <= _size)
if(_size == _capacity)
{
reverse(_capacity == 0?4:2*_capacity);
}
for(size_t i = _size; i>pos; i--)
{
_str[i] = _str[i-1];
}
_str[pos] = ch;
_size += 1;
_str[_size] = '\0';
return *this;
}
string& insert(size_t pos = 0, const char* s)
{
assert(pos <= _size);
size_t len = _size + strlen(s);
if(len > _capacity)
{
reverse(len);
}
for(size_t i = len; i > pos; i--)
{
_str[i] = _str[i - strlen(s)];
}
for(size_t i = pos; i < pos+strlen(s); i++)
{
_str[i] = s[i-pos];
}
_size += strlen(s);
_str[_size] = '\0';
return *this;
}
(5)erase
string& erase(size_t pos = 0, size_t len = npos)
{
assert(pos < _size);
size_t leftLen = _size - pos;
if(len > leftLen)
{
_size = pos;
_str[pos] = '\0';
}
else
{
strcpy(_str+pos, _str+pos+len);
_size -= len;
}
return *this;
}
(6)pop_back
void pop_back()
{
erase(_size-1, 1);
}
五、string的遍历
(1)重载operator[ ] 的遍历方式
char& operator[](size_t i)
{
assert(i<_size);
return _str[i];
}
int main()
{
string s("hello world");
for(size_t i = 0;i < s.size(); i++)
s[i] += 1;
return 0;
}
(2)使用迭代器的遍历方式4
typedef char* iterator;
iterator begin()
{
return _str;
}
iterator end()
{
return _str+_size;
}
int main()
{
string s("hello world");
iterator it = s.begin();
while(it != s1.end())
{
cout<< *it << " ";
it++;
}
}
(3)使用范围for的遍历方式
int main()
{
string s("hello world");
for(auto ch : s)
{
cout << ch <<" ";
}
return 0;
}
六、查找
find
支持从某一位置开始,寻找子串或者字符,返回起始位置下标。因此有两个函数重载 | |
---|
size_t find(char ch, size_t pos = 0) const
{
assert(pos < _size);
for(size_t i = 0; i<_size; i++)
{
if(_str[i] == ch)
return i;
}
return npos;
}
size_t find(const char* s, size_t pos)
{
assert(pos < _size);
char* ret = strstr(_str+pos, s);
if(ret == NULL)
return npos;
else
return ret-_str;
}
七、大小比较
各种符号
bool operator>(const string& s) const
{
return strcmp(_str, s._str) > 0;
}
bool operator<(const string& s) const
{
return strcmp(_str, s._str) < 0;
}
bool operator==(const string& s) const
{
return strcmp(_str, s._str) == 0;
}
bool operator>=(const string& s) const
{
return !(*this < s);
}
bool operator<=(const string s) const
{
return !(*this>s);
}
bool operator!=(const string& s) const
{
return !(*this == s);
}
|