string的实现(下)
1.面试中的简单实现
在面试中,由于时间的缘故,我们只需要简单实现string就行,其中就包括构造函数,析构函数,拷贝构造,赋值运算即可。由于不涉及容量的改变,只需要一个成员变量_str即可。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class my_string
{
public:
my_string(const char* s = "")
:_str(new char[strlen(s)+1])
{
strcpy(_str, s);
}//构造函数
my_string(const my_string& s)
:_str(nullptr)
{
my_string s1(s.c_str());
swap(_str, s1._str); //交换首地址元素,结束旧元素的s1,会自动调用析构函数析构,一定要置原_str为空,不然就会析构错误
}//拷贝构造函数
~my_string()
{
delete[] _str;
_str = nullptr;
}
//析构函数
my_string& operator=(const my_string& s)
{
my_string s1(s);
swap(_str, s1._str);
return *this;
}
const char* c_str()const
{
return _str;
}
private:
char* _str;
};
2.复杂功能的实现
注意,其中可能掺杂了strcpy的来交换_str的传统写法,我们更倾向于在实现的时候调用库函数swap。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
using namespace std;
class my_string
{
friend istream& operator>>(istream& ci, my_string& s);
public:
my_string(const char* s="")
{
_size = _capacity = strlen(s);
_str = new char[_size + 1];
strcpy(_str, s);
}//实现了默认和带参构造
//my_string(const my_string& s)
//{
// _size = _capacity = strlen(s._str);
// _str = new char[_size + 1];
// strcpy(_str, s._str);
//}//实现拷贝构造
//拷贝构造的现代写法(使用swap)
my_string(const my_string& s)
:_str(nullptr) //如果初始化 换给s中的str后,s析构delete时就会出问题
{
my_string tmps(s._str);
swap(tmps);
}
~my_string()
{
delete[] _str;
_capacity = _size = 0;
_str = nullptr;
}
char& operator[](size_t pos)const
{
assert(pos >= 0 && pos < _size);
return *(_str + pos);
}
typedef char* iterator;
char* begin()const
{
return _str;
}
char* end()const
{
return _str + _size ;
}
void push_back(char c)
{
if (_capacity == _size)
{
size_t capacity = _capacity == 0 ? 4 : 2 * _capacity;
reserve(capacity);
}
_str[_size++] = c;
_str[_size] = '\0';
}
void append(const char* s)
{
size_t len = strlen(s);
if (_size + len > _capacity)
{
size_t capacity = _size + len;
reserve(capacity);
}
strcpy(_str + _size, s);
_size = _size + len;
}
void operator+=(char c)
{
push_back(c);
}
void operator+=(const char* str)
{
append(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 resize(size_t n,char c = '\0')
{
if (n <= _size)
{
_str[n] = '\0';
}
else
{
reserve(n);
for (size_t i = _size; i < n; i++)
{
_str[i] = c;
}
_str[n] = '\0';
}
}
my_string& insert(size_t pos, size_t n, char c)
{
assert(pos <= _size);
if (_capacity < _size + n)
{
reserve(_size + n);
}//先增容
int end = _size;
while (end >= (int)pos)
{
_str[end + n] = _str[end];
end--;
}//将pos位置后的移动,腾出n个位置
while (n)
{
_str[pos] = c;
pos++;
n--;
}
return *this;
}
my_string& insert(size_t pos, const char* str)
{
assert(pos <= _size);
size_t len = strlen(str);
if (_capacity < _size + len)
{
reserve(_size + len);
}//扩容
int end = _size;
while (end >= (int)pos)
{
_str[end + len] = _str[end];
end--;
}//腾位置
strncpy(_str + pos, str, len);
return *this;
}
my_string erase(size_t pos, size_t len = npos)
{
assert(pos < _size);
if (len >= _size - pos)
{
_str[pos] = '\0';
_size = pos;
}
else
{
for (size_t i = pos + len; i <= _size; i++)
{
_str[i - len] = _str[i];
}
}
return *this;
}
size_t find(char c, size_t pos = 0)const
{
assert(pos < _size);
for (size_t i = pos; i < _size; i++)
{
if (_str[i] == c)
{
return i;
}
}
return npos;
}
size_t find(const char* str, size_t pos = 0)const
{
assert(pos < _size);
const char* s = strstr(_str + pos, str);
if (s)
{
return s - begin();
}
return npos;
}
//my_string& operator=(const my_string& s)
//{
// delete[] _str;
// char* tmp = new char[strlen(s._str) + 1];
// strcpy(tmp, s._str);
// _str = tmp;
// return *this;
//}
// operator=的现代写法(使用swap)
///*my_string & operator=(const my_string & s)
//{
// my_string s1(s);
// swap(s1);
//}*/
my_string& operator=(my_string s)
{
swap(s);
return *this;
}
bool operator==(const my_string& s)const
{
int c = strcmp(_str, s._str);
return c == 0;
}
bool operator> (const my_string& s)const
{
int c = strcmp(_str, s._str);
return c > 0;
}
bool operator< (const my_string& s)const
{
int c = strcmp(_str, s._str);
return c < 0;
}
bool operator>=(const my_string& s)const
{
return !(*this < s);
}
bool operator<=(const my_string& s)const
{
return !(*this > s);
}
size_t size()const
{
return _size;
}
size_t capacity()const
{
return _capacity;
}
char* c_str() const
{
return _str;
}
void swap(my_string& s)
{
::swap(_str, s._str); //_str指向的是地址,所以库的swap实现了首元素地址交换,就交换了整个
::swap(_size, s._size);
::swap(_capacity, s._capacity);
}
private:
char* _str;
size_t _size;//已经有多少有效字符
size_t _capacity;//能存储多少有效字符
static size_t npos;
};
size_t my_string::npos = -1;
ostream& operator<<(ostream& cou, const my_string& s)
{
cout << s.c_str();
return cou;
}
istream& operator>>(istream& ci, my_string& s)
{
while (1)
{
char c;
c=ci.get();
if (c == '\0' || c == '\n')
{
break;
}
else
{
s.push_back(c);
}
}
return ci;
}//利用istream中的get获取单个字符