【C++】string 的底层实现

本文详细介绍了C++中自定义的字符串类实现,包括构造函数、析构函数、拷贝构造函数、赋值运算符、扩容机制、字符串操作如插入、删除、查找等,以及输入输出流的处理。同时,还涵盖了字符串类中的交换和清理功能以及比较运算符的重载。
摘要由CSDN通过智能技术生成

首先string的内置成员有:

char* _str;

size_t _size;

size_t _capacity;

static const size_t npos;

实现的原理有:

构造函数:

    string(const char* str = "")
{
    _size = strlen(str);
    _capacity = _size;
    _str = new char[_capacity + 1];
    strcpy(_str, str);
}

析构函数:

~string()
{
	delete[] _str;
	_str = nullptr;
}

拷贝函数:

//拷贝
string (const string& s)
	: _str(nullptr)
	, _size(0)
	, _capacity(0)
{
	string tmp(s._str);
	swap(tmp);
}
//string(const string& s)
//	:_str(new char[strlen(s._str) + 1])
//{
//	strcpy(_str, s._str);
//}

运算符=:

string& operator=(string s)
{
	swap(s);
	return *this;
}
//string& operator=(const string& s)
//{
//	if (this != &s)
//	{
//		delete[] _str;
//		_str = new char[strlen(s._str) + 1];
//		strcpy(_str, s._str);
//	}
//	return *this;
//}

扩容:resize、reserve

//扩容
void reserve(size_t n)
{
	if (n > _capacity)
	{
		char* tmp = new char[n + 1];
		_capacity = n;
		strcpy(tmp, _str);
		delete[] _str;
		_str = tmp;
	}
}
		
void resize(size_t n, char ch = '\0')
{
	if (n <= _size)
	{
		_str[n] = '\0';
		_size = n;
	}
	else
	{
		if (n > _capacity)
			reserve(n);
		for (size_t i = _size; i < n; i++)
		{
			_str[i] = ch;
		}
		_str[n] = '\0';
		_size = n;
	}
}

+=、ch、str:

/单个字符
void push_back(char ch)
{
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : _capacity * 2);
	}
	_str[_size] = ch;
	_str[_size + 1] = '\0';
	_size++;
}
//字符串
void append(const char* str)
{
	size_t len = strlen(str) + _size;
	if (len > _capacity)
	{
		reserve(len == 0 ? 4 : len * 2);
	}
	strcpy(_str + _size, str);
	_size = len;
}

string& operator+=(char ch)
{
	push_back(ch);
	return *this;
}

string& operator+=(const char* str)
{
	append(str);
	return *this;
}

增:

//增加
string& insert(size_t pos, char ch)
{
	assert(pos <= _size);
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : _capacity * 2);
	}
	//移动数据
	for (size_t i = _size + 1; i > pos; i--)
	{
		_str[i] = _str[i - 1];
	}
	_str[pos] = ch;
	_size++;
	return *this;
}

string& insert(size_t pos, const char* str)
{
	assert(pos <= _size);
	size_t len = strlen(str);
	if (len + _size >= _capacity)
	{
		reserve(len + _size);
	}
	//移动数据
	char* end = _str + _size;
	while (end >= _str + pos)
	{
		*(end + len) = *end;
		end--;
	}
	strncpy(_str + pos, str, len);
	_size += len;
	return *this;
}

删:

//删除
string& erase(size_t pos = 0, size_t len = npos)
{
	assert(pos <= _size);
	//1.如果len小于属于长度,则不清空
	if (len < _size - pos)
	{
		strcpy(_str + pos, _str + pos + len);
		_size -= len;
	}
	else//2.大于剩余长度,所以清空掉
	{
		_str[pos] = '\0';
		_size = pos;
	}
	return *this;
}

查、改:

//查找
size_t find(char ch, size_t pos = 0)
{
	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)
{
	assert(pos <= _size);

	char* ret = strstr(_str + pos, str);
	if (ret)
	{
		return ret - _str;
	}
	else
	{
		return npos;
	}
}

输入输出流:getline

//输入输出流
istream& operator>>(istream& in, string& s)
{
	s.clear();

	char ch;
	ch = in.get();
	while (' ' != ch && '\n' != ch)
	{
		s += ch;
		ch = in.get();
	}
	return in;
}
//getline遇到空格继续往前,找到遇到换行符
istream& getline(istream& in, string& s)
{
	s.clear();

	char ch;
	ch = in.get();
	while ('\n' != ch)
	{
		s += ch;
		ch = in.get();
	}
	return in;
}

ostream& operator<<(ostream& out, const string& s)
{
	for (auto ch : s)
	{
		out << ch;
	}

	return out;
}

交换函数:swap

void swap(string& s)
{
	::swap(_str, s._str);
	::swap(_size, s._size);
	::swap(_capacity, s._capacity);
}

清理函数:clear

//清理
void clear()
{
	_str[0] = '\0';
	_size = 0;
}

>、<、>=、<=、==、!=:

//运算符重载
bool operator>(const string& s1, const string& s2)
{
	return strcmp(s1.c_str(), s2.c_str()) > 0;
}
bool operator==(const string& s1, const string& s2)
{
	return strcmp(s1.c_str(), s2.c_str()) == 0;
}
bool operator>=(const string& s1, const string& s2)
{
	return (s1 > s2) || (s1 == s2);
}
bool operator<(const string& s1, const string& s2)
{
	return !(s1 >= s2);
}
bool operator<=(const string& s1, const string& s2)
{
	return !(s1 > s2);
}
bool operator!=(const string& s1, const string& s2)
{
	return !(s1 == s2);
}

迭代器:begin、end

typedef char* iterator;
//头
iterator begin() const
{
	return _str;
}
//尾
iterator end() const
{
	return _str + _size;
}
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值