C++之string的底层简单实现!(七千字长文详解)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++之string的底层简单实现!(七千字长文详解)相关的知识,希望对你有一定的参考价值。
C++之string的底层简单实现!
string之私有成员变量
namespace MySTL
class string
private:
char* _str;
size_t _size;
size_t _capacity;
//这里capacity表示的是实际可以存的内存的大小!
//也可以表示真实的内存大小!
const static size_t npos = -1;
;
string构造函数
string(const char* str = "")
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
strcpy(_str, str);
string的拷贝构造
string(const string& str)
_str = new char[str._capacity + 1];
strcpy(_str, str._str);
_capacity = str._capacity;
_size = str._size;
= 重载!
string& operator=(const string& str)
if (this == &str)
char* temp = new char[str._capacity + 1];
strcpy(temp, str._str);
delete[] _str;//比起拷贝构造要多一步先把原来自己的空间释放掉!
_str = temp;
_capacity = str._capacity;
_size = str._size;
return *this;
string的析构函数
~string()
_size = _capacity = 0;
delete[] _str;
_str = nullptr;
string的迭代器
typedef char* iterator;
begin
iterator begin()
return _str;
end
iterator end()//迭代器的最后一个指向有效数据的下一位!
return _str + _size;
string的const迭代器
typedef const char* const_iterator;
begin
const_iterator begin()const
return _str;
end
const_iterator end()const
return _str + _size;
size
size_t size()const
return _size;
capacity
size_t capacity()const
return _capacity;
[]重载!
char& operator[](size_t pos)
assert(pos < _size);
return _str[pos];
const char& operator[](size_t pos)const
assert(pos < _size);
return _str[pos];
reserve
void reserve(size_t n)
char* temp = new char[n + 1];
strcpy(temp, _str);
delete[] _str;
_str = temp;
_capacity = n;
resize
void resize(size_t n, char ch = \\0)
assert(n >= 0);
if (n <= _size)
_str[n] = \\0;
_size = n;
else if (n > _size && n <= _capacity)
while (_size < n)
_str[_size] = ch;
_size++;
_str[_size] = \\0;
else
reserve(n);
while (_size < n)
_str[_size] = ch;
_size++;
_str[_size] = \\0;
_capacity = n;
插入类接口!
Push_Back
void Push_Back(char c)
if (_size == _capacity)
size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
reserve(newcapacity);
_capacity = newcapacity;
_str[_size] = c;//这是\\0的位置!
_size++;
_str[_size] = \\0;//最后记得加上\\0
append
void append(char c)
Push_Back(c);
//插入单个的字符,逻辑是根Push_Back是一样的!
void append(const char* str)
size_t len = strlen(str);
if (_size + len > _capacity)
reserve(_size + len);
//strcat(_str, str);
strcpy(_str + _size,str);
//上面两种实现方式都可以!
//strcpy已经吧\\0都拷贝到_str里面了
_size += len;
//插入一个字符串,也要进行扩容!
//但是不能二倍扩容!因为不能保证二倍扩容的空间大小是足够的!
+=重载
string& operator+=(char c)
Push_Back(c);
return *this;
string& operator+=(const char* str)
append(str);
return *this;
insert
插入一个字符
插入一个字符串
erase
string& erase(size_t pos, size_t len = npos)
size_t end = _size;
if (len == npos || len >= _size - pos)
_str[pos] = \\0;
_size = pos;
//当len不传值的时候,和len大于剩下空间的时候!
else
strcpy(_str + pos, _str + pos + len);
_size -= len;
return *this;
find
size_t find(char ch, size_t pos = 0)const
assert(pos < _size);
for (size_t i = pos; i < _size; i++)
if (_str[i] == ch)
return i;
return npos;
size_t find(const char* str, size_t pos = 0)const
const char* ptr = strstr(_str + pos, str);//要加pos是因为从pos的位置开始找的!
if (ptr == nullptr)
return npos;
else
return ptr - _str;
clear
void clear()
_str[0] - \\0;
_size = 0;
>>的重载!
ostream& operator<< (ostream& out, const string& str)
for (size_t i = 0; i < str.size(); i++)
out << str[i];
return out;
<< 重载!
istream& operator >>(istream& in, string& str)
str.clear();
char ch;
in >> ch;
while (ch != \\n && ch != )
in >> ch;
str += ch;
str += \\0;
return in;
正确写法!
istream& operator >>(istream& in, string& str)
str.clear();
char ch;
ch = in.get();
while (ch != \\n && ch != )
str += ch;
ch = in.get();
return in;
==最终优化版!==
istream& operator >>(istream& in, string& str)
str.clear();//用来清空str保留的数据!
char buff[128] = \\0 ;
char ch;
ch = in.get();
int i = 0;
while (ch != \\n && ch != )
if (i == 127)//留一个用来存放\\0 如果i == 128的话!会导致乱码!因为+=的底层是append,append是调用strcpy来实现的!strcpy是以\\0作为结尾的!
i = 0;
str += buff;
buff[i++] = ch;
ch = in.get();
if (i > 0)
buff[i] = \\0;//如果不加上这个的话会把后面原本的值都拷进去!
str += buff;
return in;
//getline的实现原理就是把条件换成while (ch != \\n)
最终代码
namespace MySTL
class string
public:
typedef char* iterator;
typedef const char* const_iterator;
iterator begin()
return _str;
const_iterator begin()const
return _str;
iterator end()
return _str + _size;
const_iterator end()const
return _str + _size;
string(const char* str = "")
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
strcpy(_str, str);
~string()
_size = _capacity = 0;
delete[] _str;
_str = nullptr;
string(const string& str)
_str = new char[str._capacity + 1];
strcpy(_str, str._str);
_capacity = str._capacity;
_size = str._size;
string& operator=(const string& str)
if (this == &str)
char* temp = new char[str._capacity + 1];
strcpy(temp, str._str);
delete[] _str;
_str = temp;
_capacity = str._capacity;
_size = str._size;
return *this;
const char* c_str()const
return _str;
size_t size()const
return _size;
size_t capacity()const
return _capacity;
char& operator[](size_t pos)
assert(pos < _size);
return _str[pos];
void reserve(size_t n)
char* temp = new char[n + 1];
strcpy(temp, _str);
delete[] _str;
_str = temp;
_capacity = n;
void resize(size_t n ,char ch = \\0)
assert(n >= 0);
if (n <= _size)
_str[n] = \\0;
_size = n;
else if (n > _size && n <= _capacity)
while (_size < n)
_str[_size] = ch;
_size++;
_str[_size] = \\0;
else
reserve(n);
while (_size < n)
_str[_size] = ch;
_size++;
_str[_size] = \\0;
_capacity = n;
void Push_Back(char c)
if (_size == _capacity)
size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
reserve(newcapacity);
_capacity = newcapacity;
_str[_size] = c;
_size++;
_str[_size] = \\0;
void append(char c)
Push_Back(c);
void append(const char* str)
size_t len = strlen(str);
if (_size + len > _capacity)
reserve(_size + len);
//strcat(_str, str);
strcpy(_str + _size, str);
_size += len;
string& operator+=(char c)
Push_Back(c);
return *this;
string& operator+=(const char* str)
append(str);
return *this;
const char& operator[](size_t pos)const
assert(pos < _size);
return _str[pos];
string& insert(size_t pos, char c)
if (_size == _capacity)
size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
reserve(newcapacity);
_capacity = newcapacity;
size_t end = _size + 1;
while (end > pos)
_str[end] = _str[end - 1];
end--;
_str[pos] = c;
_size++;
return *this;
string& insert(size_t pos, const char* str)
size_t len = strlen(str);
if (_size + len > _capacity)
reserve(_size + len);
size_t end = _size + len;
while (end >= pos + len)
_str[end] = _str[end - len];
end--;
strncpy(_str + pos, str, len);
_size += len;
return *this;
string& erase(size_t pos, size_t len = npos)
size_t end = _size;
if (len == npos || len >= _size - pos)
_str[pos] = \\0;
_size = pos;
else
strcpy(_str + pos, _str + pos + len);
_size -= len;
return *this;
size_t find(char ch, size_t pos = 0)const
assert(pos < _size);
for (size_t i = pos; i < _size; i++)
if (_str[i] == ch)
return i;
return npos;
size_t find(const char* str, size_t pos = 0)const
const char* ptr = strstr(_str + pos, str);
if (ptr == nullptr)
return npos;
else
return ptr - _str;
void clear()
_str[0] - \\0;
_size = 0;
private:
char* _str;
size_t _size;
size_t _capacity;
const static size_t npos = -1;
;
ostream& operator<< (ostream& out, const string& str)
for (size_t i = 0; i < str.size(); i++)
out << str[i];
return out;
istream& operator >>(istream& in, string& str)
str.clear();
char buff[128] = \\0 ;
char ch;
ch = in.get();
int i = 0;
while (ch != \\n && ch != )
if (i == 127)
i = 0;
str += buff;
buff[i++] = ch;
ch = in.get();
if (i >= 0)
buff[i] = \\0;
str += buff;
return in;
以上是关于C++之string的底层简单实现!(七千字长文详解)的主要内容,如果未能解决你的问题,请参考以下文章
C++ 之string类常用接口功能解析(7千字长文带你玩懂string!)