目录
strcpy
strcpy是将'/0'拷贝完成后才会停止。
构造函数
string()
:_str(nullptr)
{}
string(char* str)
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
注:不能直接用str初始化_str因为
char*p ="hello";
p在栈区 hello 在代码区 代码区存放常量,常量不能被修改。
优化
string()
:_str(new char[1])
{
_str[0] = '\0';
}
没有'\0'调size()时会发生崩溃。
拷贝构造/深拷贝
//string s2(s1);
string(const string& s)
:_str(new char[strlen(s._str)+1])
{
strcpy(_str, s._str);
}
浅拷贝会使两个对象的_str指向同一快空间,必须用深拷贝在开辟一块空间使其指向不同空间
operator=
//s1=s2 s1.operator(s2)
string& operator=(const string& s)
{
if (this != &s)
{
char* tmp = new char[strlen(s._str) + 1];
strcpy(tmp, s._str);
delete[] _str;
_str = tmp;
return *this;
}
}
紫色区域可以理解为tmp
size/operator[]
size_t size()
{
return strlen(_str);
}
char& operator[](int i)
{
return _str[i];
}
const char& operator[](int i) const//修饰this指针
{
assert(i < _size);
return _str[i];
}
const char& operator[](int i) const//修饰隐含this指针
operator<<
ostream& operator<<(ostream& out,const string& s)
{
for (int i = 0; i < s.size(); i++)
{
out << s[i] << " ";
}
out << endl;
return out;
}
不访问私有成员变量或函数必须用友元类。
c_str()
char* c_str()
{
return _str;
}
模拟string::iterator
typedef char* iterator;
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
插入
push_back()
void push_back(char ch)
{
if (_size == _capacity)
{
size_t newcapacity = _capacity == 0 ? 2 : _capacity * 2;
char* newstr = new char[newcapacity + 1];
strcpy(newstr, _str);
delete[] _str;
_str = newstr;
_capacity = newcapacity;
}
_str[_size] = ch;
++_size;
_str[_size] = '\0';
}
没有'\0'会出现乱码
append()
void append(const char* str)//"aa"
{
size_t len = strlen(str);
if (len + _size > _capacity)
{
size_t newcapacity = len + _size;
char* newstr = new char[newcapacity + 1];
strcpy(newstr, _str);
delete[] _str;
_str = newstr;
_capacity = newcapacity;
}
strcpy(_str + len, str);
_size += len;
}
operator+=
//s1+='a'
string& operator+=(char ch)
{
this->push_back(ch);
return *this;
}
//s1+="a"
string& operator+=(const char* str)
{
this->append(str);
return *this;
}
s1传给*this;
reserve
void reserve(int n)
{
if (n > _capacity)
{
//
char* newstr = new char[n + 1];//'\0'
strcpy(newstr, _str);
delete[] _str;
_str = newstr;
_capacity = n;
}
}
开空间拷数据释放旧空间
npos
static size_t npos;
size_t string::npos = -1;
简单的string类
namespace my_string
{
using namespace std;
//class string
//{
//public:
// /*string()
// :_str(new char[1])
// {
// _str[0] = '\0';
// }
// string(char* str)
// :_str(new char[strlen(str) + 1])
// {
// strcpy(_str, str);
// }*/
// string(const char* str = "")
// :_str(new char[strlen(str) + 1])
// {
// strcpy(_str, str);
// }
// //string s2(s1);
// string(const string& s)
// :_str(new char[strlen(s._str)+1])
// {
// strcpy(_str, s._str);
// }
// //s1=s2 s1.operator(s2)
// string& operator=(const string& s)
// {
// if (this != &s)
// {
// char* tmp = new char[strlen(s._str) + 1];
// strcpy(tmp, s._str);
// delete[] _str;
// _str = tmp;
// return *this;
// }
// }
// size_t size()
// {
// return strlen(_str);
// }
// char& operator[](int i)
// {
// return _str[i];
// }
// char* c_str()
// {
// return _str;
// }
// ~string()
// {
// delete[] _str;
// _str = nullptr;
// }
//private:
// char* _str;
//};
//void test_string()
//{
// string s1("hello");
// string s2(s1);
// cout << s1.c_str() << endl;
// cout << s2.c_str() << endl;
//}