C++---string类接口整理与深浅拷贝

string:是表示字符串序列的类,不能操作多字节或者变长字符序列
在使用string类时,必须包含#include头文件以及using namespace std;

常见的接口整理

  • 常见的string的构造函数
函数名称 功能说明
string() 调用默认构造函数,构造一个空串
string(const char *s) 用C_string构造string类对象
string(size_t n,char c) 用n个字符c构造string类对象
string(const string& s) 拷贝构造函数
	string s1;
	string s2("hello world");
	string s3(5, 'c');
	string s4(s1);
  • 容量操作
接口名 功能说明
size 返回有效字符的个数
length 返回有效字符的个数,与size效果相同
capacity 返回空间的总大小
empty 判空操作,如果字符串为空串返回true,否则返回false
clear 清空字符串
reserve 为字符串预留空间
resize 将有效字符改为n个,其余的用字符c填充,默认字符c为空

说明
size()与length()的方法实现原理相同,引入size()就是为了与其他容器的接口保持一致。
clear()只是清除有效字符,不改变底层空间的大小
resize(size_t n)表示将有效空间的大小改为n,多余的空间用0填充,resize(size_t n,char c)也表示将有效的空间大小改为n,多余的空间用字符c填充
reverse(size_t n)表示为string预留空间,不改变有效元素的个数,如果n小于当前的capacity则空间大小不变,如果大于capacity则增加空间大小,不同的编译器增容机制不同,vs增容大小为1.5capacity

	string s1("hello world");
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	cout << s1.capacity()<<endl;
	s1.resize(13);
	cout << s1;
	s1.reserve(40);
	cout << s1.capacity() << endl;
  • 遍历
接口名 功能说明
operator[] 返回pos位置的字符
begin / end 迭代器,begin获取第一个字符,end获取最后一个字符的下一个位置
rbegin / rend 反向迭代

说明
begin,end迭代器,返回的范围为[begin,end)左闭右开,表示end位置的元素取不到

string s1("hello world");
	for (size_t i=0; i < s1.size(); ++i)
	{
		cout << s1[i]<<" ";
	}
	cout << endl;
	auto it = s1.begin();
	while (it != s1.end())
	{
		cout << *it;
		it++;
	}
  • 类对象的操作
接口名 功能介绍
push_back 尾插
append 追加一个字符串
operator+= 追加字符串
c_str 返回c格式的字符串
find+npos 从npos的位置往后找字符c,返回字符c所在的位置
rfind 从后往前找
substr 截取字符串

string类浅拷贝

//浅拷贝代码
class String
{
public:
	String(const char* str = "")
	{
		if (str == nullptr)
		{
			assert(str);
			return;
		}
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
private:
	char *_str;
};

上面代码没有显示定义string类的拷贝构造函数,所以系统会调用默认的拷贝构造函数,但是默认的拷贝构造函数为浅拷贝,当函数结束时,调用析构函数时,会造成空间释放错误。
C++---string类接口整理与深浅拷贝_第1张图片C++---string类接口整理与深浅拷贝_第2张图片

  • 浅拷贝的解决办法(一)
class String
{
public:
	String(const char* s = "")
	{
		if(s==nullptr)
		{
			assert(s);
			return;
		}
		_str = new char[strlen(s) + 1]; 
		strcpy(_str,s);
	}
	String(String& s)
		:_str(new char[strlen(s._str) + 1];
	{
		strcpy(_str,str);
	}
	String operator = (const String& s)
	{
		if(this!=&s)
		{
			char *temp = new char[strlen(s._str) + 1];
			strcpy(temp,s._str);
			delete _str;
			_str = temp;
		}
		return *this;
	}
private:
	char* _str;
}
void test()
{
	String s1("hello");
	String s2(s1);
	String s3 = s1;
}
int main()
{
	test();
	return 0;
}

在这里插入图片描述

  • 浅拷贝的解决办法(二)
class String
{
public:
	String()
	{}
	String(const char* s = "")
	{
		size_t _capacity = strlen(s);
		_str = new char[_capacity+1];
		strcpy(_str, s);
	}
	String(const String& s)
		:_str(nullptr)
	{
		String temp(s._str);
		swap(_str,temp._str);
	}
	String operator = (const String& s)
	{
		if(this!=&s)
		{
			String temp(s._str);
			swap(_str,temp._str);
		}
		return *this;
	}
	~String()
	{
		if (_str != nullptr)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
	void Swap(String & s)
	{
		swap(_str, s._str);
	}
private:
	char *_str;
};

在这里插入图片描述
String类的模拟实现

class String
{
public:
	typedef char* iterator;
	String(const char* s = "")
		:_size(0)
		,_capacity(0)
		,_str(new char[strlen(s) + 1])
	{
		
		_size = strlen(s);
		_capacity = 15;
		strcpy(_str, s);
	}
	String(const String& s)
	{
		String temp(s._str);
		this->Swap(temp);
	}
	String operator = (const String& s)
	{
		if (this != &s)
		{
			String temp(s._str);
			this->Swap(temp);
		}
		return *this;
	}
	void Swap(String& s)
	{
		swap(_str, s._str);
		swap(_size, s._size);
		swap(_capacity, s._capacity);
	}
	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
	iterator begin()
	{
		return _str;
	}
	iterator end()
	{
		return _str + _size;
	}
	String& operator += (char c)
	{
		pushBack(c);
		return *this;
	}
	void Append(char c)
	{
		pushBack(c);
	}
	void Clear()
	{
		_size = 0;
		_str[_size] = '\0';
	}
	const char* C_str()const
	{
		return _str;
	}
	size_t size()
	{
		return _size;
	}
	size_t capacity()
	{
		return _capacity;
	}
	bool Empty()const
	{
		if (_size > 0)
			return false;
		else
			return true;
	}

	const char& operator[](size_t index)const
	{
		assert(index < _size);
		return _str[index];
	}
	bool operator == (const String& s)
	{
		if (strcmp(_str, s._str) == 0)
			return true;
		return false;
	}
	bool operator !=(const String& s)
	{
		return !operator==(s);
	}
	bool operator > (const String& s)
	{
		if (strcmp(_str, s._str) > 0)
			return true;
		return false;
	}
	bool operator >= (const String& s)
	{
		if (strcmp(_str, s._str) >= 0)
			return true;
		return false;
	}
	bool operator < (const String& s)
	{
		if (strcmp(_str, s._str) < 0)
			return true;
		return false;
	}
	bool operator <= (const String& s)
	{
		if (strcmp(_str, s._str) <= 0)
			return true;
		return false;
	}
	void pushBack(char c)
	{
		if (_size == _capacity)
			Reverse(2 * _capacity);
		_str[_size++] = c;
		_str[_size] = '\0';
	}
	void Resize(size_t Newsize,char c = '\0')
	{
		if (Newsize > _size)
		{
			if (Newsize > _capacity)
			{
				Reverse(Newsize);
			}
			memset(_str + _size, c, Newsize);
		}
		_size = Newsize;
		_str[_size] = '\0';
	}
	void Reverse(size_t Newcapacity)
	{
		if (Newcapacity > _capacity)
		{
			char* str = new char[Newcapacity + 1];
			strcpy(str, _str);
			delete[] _str;
			_str = str;
			_capacity = Newcapacity;
		}
	}
	

private:
	friend ostream& operator<<(ostream& _cout,  String& s);
	friend istream& operator >> (istream& _cin, String& s);
	char *_str;
	int _size;
	int _capacity;
};

ostream & operator<<(ostream & _cout,  String & s)
{
	_cout << s._str;
	return _cout;
}
istream& operator >> (istream& _cin, String& s)
{
	s._str = new char[256];
	_cin >> s._str;
	return _cin;
}
void test()
{
	String s1("hello");
	cout << s1.size();
	String s2(s1);
	String s3 = s1;
	s1 += 't';
	cout<<s1.size();
	cout << s1;
	cout << endl;
	auto it = s1.begin();
	while (it != s1.end())
	{
		cout << *it;
		it++;
	}
	s1.pushBack('!');
	cout << s1;
}

你可能感兴趣的:(C++---string类接口整理与深浅拷贝)