string类常用接口简介与简单模拟实现

string类是C++中常用的一个针对字符串管理所设计的的字符串类

一.string的一些常用的接口

1.常见的string类构造接口

string()        //构造一个空的string类对象
string(const char* s)  //以C格式的字符串,来构造出一个string类对象
string(size_t n,char c)  //用n个字符c来构造一个string类对象
string(const string& s)  //拷贝构造
string(const string& s,pos n) //从对象s的位置n起拷贝构造出新的string类对象

用法示例

int main()
{
	string s1;            //构造出空的string类对象s1
	string s2("hello ");  //用C格式字符串构造出string类对象s2
	string s3("world");   //同上
	string s4(11, 't');   //用11个字符t构造string类对象s4
	string s5(s3);         //用s3拷贝构造s5
	string s6(s3, 0);

//因为没有包<string>,因此需要用->对象.c_str()的方法将string转化为char*的方式进行输出
	cout<<s3<<endl;//报错
	cout << (s1 = s2).c_str() << endl;
	cout << s3.c_str() << endl;

	//包了string头文件之后,即可正常输出
	cout << s6 << endl;//输出world
	//...
	return 0;
}

2.string类对象的容量操作函数

size_t size()const          //返回字符串有效长度
size_t length()const        //同上              //size与length原理相同
size_t capacity()const      //返回对象空间大小
bool empty()const           //判空,空返回true即(1),非空返回false(0)
void clear()                //清空有效字符//但不改变其空间大小
void resize(size_t n,char c)//将对象的有效字符串个数改为n个,剩余的用字符c填充
void resize(size_t n)       //同上,但剩余个数使用0进行填充
void reserve(size_t n)      //为对象预留空间

注意:
1.resize在改变对象有效个数时,如果是将有效元素个数增大,有可能导致对象底层容量(即capacity)的增大,但若将有效元素减少,则不会不会引起容量的变化。
2.reserve为对象预留空间时,不会改变对象的有效个数。当其参数大于原空间时会扩容至参数大小,但因为考虑到内存对齐,其实际可能比参数要大上一点,如果是一点一点的增加对象的有效个数所导致的增容,reserve大概会按1.5倍的方式进行增容;当参数小于原空间大小时,则不会改变对象容量大小。
3.访问操作

char& operator[](size_t pos)           //返回对象pos位置处的字符,非const对象调用
const char& operator[](size_t pos)const//同上,const对象调用

用法示例

//一般会用在遍历字符串中
int main()
{
   //创建一个非const的对象,即可读,也可写
   string s("hello world");
   //与size()配合,使其支持类似于数组的访问
   for(int i=0;i<s.size();++i)
     {
         s[i]+=1;
         cout<<s[i]<<' ';
      }
      cout<<endl;
      //范围for遍历
      //底层会被替换为迭代器
    for (auto ch : s)
	{
		cout << ch << ' ';
	}
	cout << endl;
	//迭代器遍历
	//string::reverse_iterator       //反向迭代器
	//string::const_reverse_iterator //反向const迭代器
	string::iterator it = s.begin();
	while (it != s.end())
	{
	    *it-=1;
		cout << *it << ' ';
		++it;
	}
	cout << endl;
return 0;
}

4.修改操作

void push_back(char c)                       //尾插字符c
string& append(const char* s)                //追加一个字符串s
string& operator+=(const string& str)        //追加一个string类对象str
string& operator+=(const char* str)          //追加一个字符串
string& operator+=(char c)                   //追加字符c
const char*c_str()const                      //返回C格式的字符串
size_t find(char c,size_t pos=0)             //从pos位置开始找字符c,不给pos默认从开始找,返回c的位置
size_t rfind(char c,size_t pos=npos)          //从pos位置开始往前找字符c,并返回其位置,npos为字符串最后一个位置,也就是说其默认从最后一个开始找
string substr(size_t pos=0,size_t n=npos)const //从pos位置开始,往后截取n个字符,然后返回//默认从pos位置开始往后截取完字符串为止
string erase(size_t begin,size_t end)           //删除字符串[begin,end]位置之间的元素,并返回删除之后的字符串

注意:
1.对string对象进行操作时,最好将其空间用resere()预留好,以防止增容带来的不必要开销。
2.对string对象追加字符串或字符时,推荐使用+=,可读性高,功能齐全。

//find(),substr()的用例示范
int main()
{
  		// 取出s中的域名
		string s("http://www.cplusplus.com/reference/string/string/find/");
		cout << s << endl;
		//找到://中:的位置
		size_t start = s.find("://");
        //跳过://
		start += 3;
		//从start开始向后找第一个/的位置
		size_t finish = s.find('/', start);
		//从start开始截取finish个字符,构成一个新串
		string address = s.substr(start, finish - start);
		cout << address << endl;//输出:www.cplusplus.com
}

5.string类的非成员函数

operator>>            //输入运算符重载
operator<<            //输出运算符重载
getline               //获取一行字符串,遇到空格不结束,换行结束
relational operators  //大小比较

二.string的简单实现

实现前首先要了解,string类对象中存储的是指针,在指针指向的数组中存储字符,要保证字符的结尾必须有’\0’的存在。

以下对其构造,拷贝构造,赋值运算符重载和析构函数的简单实现。

class my_string
{
  public:
      	//构造
	String(const char* str = "")//""里边存了一个'\0'
	//不在初始化的时候就开空间,是为了保证String(nullptr)的正常
	//否则strlen(nullptr)就直接报错了
	{
		if (str == nullptr)
		{
              str = "";
		}
		_str = new char[strlen(str) + 1];
       //上俩句保证让String(nullptr),也能构造出一个空对象

		strcpy(_str, str);
	}
	//拷贝构造
   String(const String& s)
		:_str(new char[strlen(s._str)+1])
	{
		strcpy(_str, s._str);
	}
	//赋值运算符重载
	String& operator=(const String& s)
	{
		if (this != &s)//防止自己给自己赋值
		{
			char* pStr = new char[strlen(s._str) + 1];
			strcpy(pStr, s._str);
			delete[] _str;
			_str = pStr;
		}
				return *this;
	}
	//析构
	~String()
	{
		if (_str)//不空在做如下操作//空就不做处理即可
		{
			delete[] _str;
			_str = nullptr;
		}
	}
  private:
      char* _str;
}

测试:

int main()
{
  	String s("hello world");
	String s1(s);//验证拷贝构造是否解决了浅拷贝问题
	String s2;//验证构造函数,是否能构建出空的字符串对象
	String s3=s1;//验证赋值运算符重载

    return 0}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值