当前位置:首页 > 编程笔记 > 正文
已解决

【C++】容器string的常用成员函数接口

来自网友在路上 11018101提问 提问时间:2023-11-19 09:42:34阅读次数: 101

最佳答案 问答题库1018位专家为你答疑解惑

目录

string - C++ Reference

1 容量相关

1.1 size/length

1.2 capacity

1.3 resize

1.4 reserve

1.5 empty

2 运算符重载

2.1 operator=

2.2 operator[]

2.3 operator+(非成员函数)

2.4 operator+=

2.5 operator>> && operator<<(非成员函数)

3 增删查改的接口

3.1 push_back

3.2 append

3.3 insert 

3.4 erase

3.5 assign

3.6 find


string - C++ Reference

1 容量相关

1.1 size/length

size和length表示string里存储的有效数据的大小/长度。 

可以用来for循环遍历string:

string str("hello string");
for(int i = 0;i < str.size();++i)
{cout<<str[i];//[]重载
}
string str("hello string");
for(int i = 0;i < str.length();++i)
{cout<<str[i];//[]重载
}

注:

length用来表示线性数据结构的有效数据长度大小,size既可以用来表示线性数据结构的有效数据大小、也可以用来表示非线性结构的有效数据大小,可以说size是通用的


1.2 capacity

capacity表示已经分配的空间的大小,通常capacity>=size/length


1.3 resize

顾名思义,改变string对象的size,有两个函数重载

体现为两个方面:

①如果传入的n<原先的长度,仅仅会删除数据,不作数据修改,因此有效重载函数形式为

void resize(size_t n)

 vs编译器:

g++:

②如果传入的n>原先的长度,不仅会改变容量,而且可以指定增加的数据,因此有效函数重载形式为:

void resize (size_t n)
void resize (size_t n, char c)

 vs编译器:

指定增加的字符为'x':

不指定增加的字符,可能放入的都是\0: 

 g++:

 不指定增加的字符,可能放入的都是\0:


1.4 reserve

顾名思义,reserve会改变capacity,而不会改变数据,因此传入的参数n大于原先的capacity才有效果!

vs编译器:

g++:


1.5 empty

 函数返回类型为真或者假


2 运算符重载

2.1 operator=


我们原本以为的赋值运算符重载:

第二行还有报错,报错信息是:

实际上这并不是赋值运算符重载,实际的运算符重载应该是这样的:

vs下=号的颜色都变了,说明两次=的作用是不一样的。为什么呢?

这下我们明白了,之所以第二次是赋值运算符重载,是因为s1、s2、s3都已经初始化好了,而且都是调用的默认构造函数string() 。

赋值运算符的运算顺序是自右向左的,s1先赋值给s2,s2再赋值给s3。 


2.2 operator[]

operator[]为我们提供了通过下标直接访问字符串内容的便利,有两种函数重载,一种给普通对象,另一种给const对象。


2.3 operator+(非成员函数)

Concatenate strings:连接字符或字符串 

用法:

为什么这个重载是非成员函数呢?

        我们都知道成员函数的第一个参数是隐藏的this指针,指向实例化出来的对象, 因此如果把+重载写在类里面也就是成员函数,第一个参数就必然是实例化出来的对象,而相加的两个对象不必一定要有this,可以是其他的两个对象,所以STL库就把它设计成非成员函数。


2.4 operator+=

官网里的例子:

和赋值重载一样,需要先进行初始化调用构造函数才能进行+=重载!

operator+=可以很方便地进行字符串尾插的操作,相当于尾插,尾插前先检查容量,容量不够先扩容再尾插。下面还有append、insert等的接口函数,也是用来进行字符串增加的。


2.5 operator>> && operator<<(非成员函数)

为了方便输入和直接输出string里的内容,设计出了流插入和流提取的重载。

这两个必须设计成非成员函数否则就会导致cout和str的顺序颠倒:str<<cout

因为左右操作数和函数的传参类型要一致,成员函数的第一个参数永远是this指针!


3 增删查改的接口

3.1 push_back

尾插会先检查容量,容量不够先扩容,然后在进行尾插操作。尾插结束后再补一个\0,模拟一下:

void push_back(char c)
{if (_capacity == _size){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = c;_size++;_str[_size] = '\0';
}


3.2 append

append提供了六种函数重载,可以看作push_back的plus版本。

string s = "hello";
string _s = " string";
s.append(_s);//hello string
s.append(_s,0,3);//hello st
s.append(" string");//hello string
s.append(" string", 2);//hello s
s.append(5,'x');//helloxxxxx
s.append(_s.begin(),_s.begin()+2);//hello s

讲解一下第二种和第四种:

substring(2):

string& append (const string& str, size_t subpos, size_t sublen)
string s = "hello";
string _s = " string";
s.append(_s,0,3);//hello st

功能:将副串_s的一部分尾插至主串s之后。

注:

subpos必须小于等于sublen,否则就会: 

如果sublen大于strlen(_s),编译器会多开空间吗? 

vs编译器:

g++:

答案是不会!

buffer(4):

string& append (const char* s, size_t n)
string s = "hello";
s.append(" string", 3);
cout<<s;//hello st

功能:将常量字符串的一部分尾插至s。

注:

如果传入的参数n大于strlen(s),编译器会多开空间吗?

vs编译器:

g++:

答案是会的! 


3.3 insert 

由于顺序表头插的时间复杂度为O(n),效率较低,所以STL库并没有实现string的头插接口,而是设计了一个insert,可以用来在pos位置插入字符或字符串,特殊的当pos为0时,就相当于头插。

其中前四种的设计和上面append的设计类似,后三种多了迭代器的传参:

void insert(iterator p,size_t n,char c);
iterator insert (iterator p, char c);
template <class InputIterator>void insert (iterator p, InputIterator first, InputIterator last);

第一种的用法:

第二种用法:

第三种用法:


3.4 erase

顾名思义,删除字符串中的字符。

用法:

第一种:


缺省参数pos=0,len=(size_t)(-1)=2^32-1

第二种:

传入迭代器,删除迭代器指向的单个字符,并返回迭代器。

顺序是先删除h再把删除后的s.begin()赋值给it。

第三种:

范围删除并返回迭代器,范围是[first,last),左闭右开!


3.5 assign

assign的用法其实就是新串代替旧串,举一个例子就行:


3.6 find

find还是挺好用的,至少不用自己写字符串查找算法,找到了就返回找到的最开始的位置,找不到就返回(size_t)(-1)。

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"【C++】容器string的常用成员函数接口":http://eshow365.cn/6-39136-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!