底层还是对字符串数组的操作
构造函数 、深拷贝、swap、析构
- 模拟实现加上时命名空间。
构造函数
namespace MyString
{
class string
{
private:
char* _a;
_size;
_cap;
public:
...
}
};
string(const char* s)
:_size(strlen(s)) //防止是无参空串 ,先测长度
, _cap(_size)
{
_a = new char[_cap + 1];
strcpy(_a, s); //字符串拷贝到实例化的新对象这里
}
Swap
void swap(string& s)
{
//标准库里的swap
::swap(_a, s._a);
::swap(_size, s._size);
::swap(_cap, s._cap);
}
/*template<class T> //标准库里面的swap函数模板
void swap(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}*/
深度拷贝构造
string(const string& s)
:_a(nullptr)
{
string tmp(s._a); //临时tmp出了这个域自动析构
// === this->swap(tmp)
swap(tmp);
}
析构
~string()
{
delete[] _a;
_str = nullptr;
_size = 0;
_capacity = 0;
}
resize 、 reserve
resize
开空间,并初始化;rserve
只对cap
扩容负责
resize
void resize(size_t n, char ch='0')
{
/小于直接腰斩
if (n<=_size)
{
_size = n;
_a[_size] = '\0'; /不传默认用 0
}
else
{
if (n>_cap)
{
reserve(n); /开n个就好了
}
for (size_t i = _size; i < n; i++)
{
_a[_size] = ch; /新开的初始化
}
_size = n;
_a[_size] = '\0';
}
}
reserve
void reserve(size_t n)
{
/开辟一块儿新的空间,拷贝源空间,销毁原空间
if (n>_cap)
{
char* tmp = new char[n + 1];
strcpy(tmp, _a);
delete[] _a;
_a = tmp;
/size 没变 容量变化了
_cap = n;
}
}
重载 [ ] 访问、 赋值重载 =
字符串数组访问,返回字符
重载 [ ]
char& operator[](size_t pos)
{
assert(pos < _size);
return _a[pos];//*(a+pos)
}
//只读的
const char& operator[](size_t pos)const
{
assert(pos < _size);
return*(_a + pos); /_a[pos];
}
赋值重载 =
string& operator=(const string& s)
{
if (this != &s)
{
string tmp(s._str);
swap(_str, tmp._str);
}
return *this;
}
+= 重载、 c_str
//字符
string& operator+=(char ch)
{
string::push_back(ch);
return *this;
}
//字符串
string& operator+=(const char* s)
{
string::append(s);
return *this;
}
void append(const char* s)
{
//追加的字符串的长度
size_t len = strlen(s);
if (_size+len>=_cap) //大于容量,扩容
{
reserve(_size + len);
}
//原字符长度尾部开始复制
strcpy(_a + _size, s);
_size += len;
}
//字符串对象
string& operator+=(const string& s)
{
*this += s._a;
return *this;
}
---//C_str
//c_str,返回对象的字符串
const char* c_str()
{
return _str;
}
getinline
从输入流输入数据,存到对象里,遇到’\n’结束输入
//输入流的类型
istream& getline(istream& in, string& s)
{
s.clear();
char ch = in.get();
while (ch != '\n')
{
s += ch;
ch = in.get();
}
return in;
}
void test_string6()
{
string s1;
getline(cin, s1);
cout << s1 << endl;
}
输入输出操作符重载:<< 、>>
输入
istream& operator>>(istream& in, string& s)
{
s.clear();
char ch;
ch = in.get();/每次获取一个字符
while (ch != ' ' && ch != '\n')
{
s += ch;
ch = in.get();
}
return in;
}
输出
ostream& operator<<(ostream& out, const string& s)
{
// 不管字符数组中的内容是啥,size是多少,就要输出多少个有效字符
for (size_t i = 0; i < s.size(); ++i)
{
out << s[i];
}
return out;
}