1.构造函数
string::string(const char*s)
:_size(strlen(s))
{
_str = new char[_size + 1];//多出来的一个来存\0,写到初始化列表中需要多次计算strlen
_capacity = _size;
strcpy(_str, s);
}
2.拷贝构造
传统写法:
string::string(const string& s)
{
_str= new char[s._capacity + 1];
strcpy(_str, s._str);
_capacity = s._capacity;
_size = s._size;
}
现代写法:
string::string(const string& s)
{
string tem(s._str);
std::swap(_str, tem._str);
std::swap(_size, tem._size);
std::swap(_capacity, tem._capacity);
}
利用构造函数实现,交换tem和*this,并且tem出作用域会调用析构函数
赋值运算符重载:
现代写法:调用了拷贝构造来进行,这里不是s的引用
string& string::operator=(string s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
return *this;
}
size():
size_t string::size()
{
return _size;
}
capacity():
size_t string::capacity()
{
return _capacity;
}
operator[ ]
char& string::operator[] (size_t pos)
{
assert(pos < _size);
return _str[pos];
}
const char& string::operator[] (size_t pos) const
{
assert(pos < _size);
return _str[pos];
}
c_str()
const char* string::c_str()const
{
return _str;
}
迭代器:
typedef char* iterator;
typedef const char* const_iterator;
用原生指针来实现
string::iterator string::begin()
{
return _str;
}
string::const_iterator string::begin() const
{
return _str;
}
string::iterator string::end()
{
return _str + _size;
}
string::const_iterator string::end() const
{
return _str + _size;
}
扩容:
reserve:
void string::reserve(size_t n)
{
if (_capacity < n)
{
char* tem = new char[n + 1];
strcpy(tem, _str);
delete[]_str;
_str = tem;
}
}
数据的增删查改
push_back
void string::push_back(char c)
{
if (_size == _capacity)
{
size_t newcapacity = _capacity * 2;
reserve(newcapacity);
}
_str[_size++] = c;
_str[_size] = '\0';
}
append:
void string::append(const char* s)
{
size_t len = strlen(s);
if (_size + len > _capacity)
{
reserve(_size + len);
}
strcpy(_str+_size, s);
_size += len;
}
insert:
void string::insert(size_t pos, char c)
{
assert(pos < _size);
if (_size == _capacity)
{
size_t newcapacity = _capacity * 2;
reserve(newcapacity);
}
for (size_t i = _size + 1; i >= pos+1; i--)
{
_str[i] = _str[i - 1];
}
_str[pos] = c;
_size++;
}
void string::insert(size_t pos, const char* s)
{
assert(pos < _size);
size_t len = strlen(s);
if (_size + len > _capacity)
{
reserve(_size + len);
}
for (size_t i = _size + len; i >= pos + len; i--)
{
_str[i] = _str[i - len];
}
memcpy(_str + pos, s, strlen(s));
_size += len;
}
erase:
void string::erase(size_t pos, size_t len)
{
if (len >= _size - pos)
{
_size = pos;
_str[_size] = '\0';
}
else
{
for (size_t i = pos; i <= _size- len; i++)
{
_str[i] = _str[i + len];
}
_size -= len;
}
}
swap
void string::swap(string& str)
{
std::swap(_str, str._str);
std::swap(_size, str._size);
std::swap(_capacity, str._capacity);
}
运算符重载:
+=:
string& string::operator+= (const char* s)
{
append(s);
return *this;
}
string& string::operator+= (char c)
{
push_back(c);
return *this;
}
> >= < <= == !=:
bool string::operator<(const string& s)
{
return !(*this <= s);
}
bool string::operator<=(const string& s)
{
return !(*this > s);
}
bool string::operator==(const string& s)
{
return strcmp(_str, s._str) == 0;
}
bool string::operator!=(const string& s)
{
return !(*this == s);
}
<<:
ostream& operator<<(ostream& cout, const string& s)
{
cout << s.c_str();
return cout;
}
>>:
istream& operator>>(istream& cin, string& s)
{
s.clear();
char ch;
char buff[128];
ch = cin.get();
int i = 0;
while (ch != ' ' && ch != '\n')
{
buff[i++] = ch;
if (i == 127)
{
buff[i] = '\0';
s.append(buff);
i = 0;
}
ch = cin.get();
}
if (i != 0)
{
buff[i] = '\0';
s.append(buff);//避免多次扩容
}
return cin;
}
>>和<<不写成友元形式是因为我们不需要访问其成员变量
find:
size_t string::find(const char* s, size_t pos) const
{
char* str = strstr(_str + pos, s);
return str - _str;
}
size_t string::find(char c, size_t pos) const
{
for (size_t i = pos; i <_size; i++)
{
if (_str[i] == c)
{
return i;
}
}
return npos;
}
substr:
string string::substr(size_t pos, size_t len) const
{
string s;
if (len >= _size - pos)
{
s.reserve(_size - pos);
s += (_str + pos);
return s;
}
else
{
for (size_t i = pos; i <= pos + len - 1; i++)
{
s.push_back(_str[i]);
}
return s;
}
}