[C++] std::string探幽
目录
1.前言
在C++标准库中,用得最多的应该是std::string类,人们经常使用它,却很少人去研究他的实现,也许要用它某个方法时才去搜索,那么如果程序员对string有深入的了解,可以更有掌控感。
众所周知,类是由成员变量和成员函数组成,即属性和行为,那么我将从这两个方面来解析string。
2.成员变量
有13个成员变量+1个静态变量,静态变量npos是存储此类最大长度的。
剩余的都是字符指针和迭代器。
string实际存储的是char型的数据。
member type | definition |
---|---|
value_type | char |
traits_type | char_traits<char> |
allocator_type | allocator<char> |
reference | char& |
const_reference | const char& |
pointer | char* |
const_pointer | const char* |
iterator | a random access iterator to char (convertible to const_iterator) |
const_iterator | a random access iterator to const char |
reverse_iterator | reverse_iterator<iterator> |
const_reverse_iterator | reverse_iterator<const_iterator> |
difference_type | ptrdiff_t |
size_type |
3.成员函数
不算重载有51个函数,具体查看点击以下链接http://www.cplusplus.com/reference/string/string/?kw=stringhttp://www.cplusplus.com/reference/string/string/?kw=string
接下来对其中的一些进行分析:
A. 其中size()和length()都可以获取长度,那么哪个是对的呢?
经过我查看源码,发现这两个函数的代码一样,所以用得时候当作同一个函数就行了。
_NODISCARD _CONSTEXPR20_CONTAINER size_type length() const noexcept {
return _Mypair._Myval2._Mysize;
}
_NODISCARD _CONSTEXPR20_CONTAINER size_type size() const noexcept {
return _Mypair._Myval2._Mysize;
}
我有一个想法,为啥不直接用size来调用length,或者反之,是为了减少函数堆栈吗?
B. std::string的内部类型是什么?
经过查看源代码有这样一段
using string = basic_string<char, char_traits<char>, allocator<char>>;
也就是说上面这两边是相等的。可以看到是一个模板类,里面为char型。
C. 存储中文有问题吗?
std::string txt1 = "hello";
std::string txt2 = "你好世界";
txt1.length()返回5,正确。
txt2.length()返回8,明显不正确,因为string是以字符存的,不在乎编码;
我在windows平台下,应该是GBK,GBK用两个字节来代表一个中文,所以"你好世界"长度为8。如果使用wstring可以解决这样的问题。
D.构造方式
// string constructor
#include <iostream>
#include <string>
int main ()
{
std::string s0 ("Initial string"); //根据已有字符串构造新的string实例
// constructors used in the same order as described above:
std::string s1; //构造一个默认为空的string
std::string s2 (s0); //通过复制一个string构造一个新的string
std::string s3 (s0, 8, 3); //通过复制一个string的一部分来构造一个新的string。8为起始位置,3为偏移量。
std::string s4 ("A character sequence"); //与s0构造方式相同。
std::string s5 ("Another character sequence", 12); //已知字符串,通过截取指定长度来创建一个string
std::string s6a (10, 'x'); //指定string长度,与一个元素,则默认重复该元素创建string
std::string s6b (10, 42); // 42 is the ASCII code for '*' //通过ASCII码来代替s6a中的指定元素。
std::string s7 (s0.begin(), s0.begin()+7); //通过迭代器来指定复制s0的一部分,来创建s7
std::cout << "s1: " << s1 << "\ns2: " << s2 << "\ns3: " << s3;
std::cout << "\ns4: " << s4 << "\ns5: " << s5 << "\ns6a: " << s6a;
std::cout << "\ns6b: " << s6b << "\ns7: " << s7 << '\n';
return 0;
}
//Output:
//s1:
//s2: Initial string
//s3: str
//s4: A character sequence
//s5: Another char
//s6a: xxxxxxxxxx
//s6b: **********
//s7: Initial
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现