目录
string类初识
string模拟实现
string类成员变量
构造函数
拷贝构造
赋值运算符重载
析构函数
深浅拷贝问题
string类初识
由于C语言中的字符串不太符合OOP(面向对象编程)的思想,而且其底层空间需要用户自己管理,经常有访问越界的情况出现。
而在C++中,为了更好地规避这些问题,就出现了string类来对字符串进行更好的封装使用,使得字符串的操作更简单,方便,快捷。
string模拟实现
string作为表示字符串的字符串类,提供了很多字符串操作的接口。平时只要能熟练地配合文档使用即可。而在面试时,很多面试官喜欢让学生模拟实现一个简单的string类。主要实现的还是string类的构造,拷贝构造,赋值运算符重载以及析构函数等。当然尝试模拟实现还能够帮助我们更好地去理解string类的底层,从而在面对出错时能更有把握地解决问题。
string类成员变量
class String
{
private:
char* _str; // 指向存放的字符串
size_t _size; // 字符串的有效长度
size_t _capacity; // 开辟空间的容量大小
};
构造函数
String(const char* str = "")
{
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
strcpy(_str, str);
}
拷贝构造
void swap(string& tmp)
{
// 复用全局的swap函数
::swap(_str, tmp._str);
::swap(_size, tmp._size);
::swap(_capacity, tmp._capacity);
}
String(const String& s)
: _str(nullptr)
, _size(0)
, _capacity(0)
{
String tmp(s._str); // 复用构造来生成临时的string对象
swap(tmp); // 通过交换来完成拷贝构造
}
赋值运算符重载
String& operator=(String s) // 在传参阶段完成拷贝构造
{
swap(s); // 交换之后完成赋值
return *this;
} // 函数调用结束,s对象销毁,空间会被回收
析构函数
~String()
{
delete[ ] _str;
_str = nullptr;
_size = _capacity = 0;
}
深浅拷贝问题
浅拷贝:也叫值拷贝。编译器只是将对象中的值进行拷贝。如果对象中存在资源管理(例如动态内存开辟),使用浅拷贝会导致多个对象共用一份资源,必然会存在“争夺”的情况。
深拷贝:让每个对象都有一份独立的资源,不要和其它对象共享,这就是深拷贝要达到的效果。如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数一般都要按照深拷贝的方式显式给出。
所以,string类的拷贝构造和赋值运算符重载必须写成深拷贝。