目录
一、定义
string 是 STL 中的一个容器,从刚学 c++ 时,我们就简单了解了字符串类型,但翻开源码,你会发现,string 库丰富,函数众多,让我们详细的了解一下吧!
string 类模板 basic_string
< char, char_traits<char>, allocator<char> > 的一个别名,是字符(char)的“串”,有四个亲兄弟:
- wstring(宽字符串
basic_string
< wchar, char_traits<wchar>, allocator<wchar> >) - u32string(32 位字符串,c++11
basic_string
< u32char, char_traits<u32char>, allocator<u32char> >) - u16string(16 位字符串,c++11
basic_string
< u16char, char_traits<u16char>, allocator<u16char> >) - u8string (8 位字符串,c++20
basic_string
< u8char, char_traits<u8char>, allocator<u8char> >)
这些模板类是对于不同类字符的版本,我们的中文在 u8string 和 string 中占三个字符的位置(不含 '\0')而在 u16string 和 u32string 中只占一个字符,至于为什么还 u8string,是因为虽然大部分系统的 CHAR_BIT 为 8,也就是说一个 char 占 1 个字节,但我们不可以默认所有系统 char 一定是 1 个字节,c++ 标准没有规定。
二、字符串字面量
"hello world!","abc","123" 这些都属于字符串字面量。
字符串字面量属于左值常量,可寻址(查询地址),不可修改,对于 char16_t[] ,
char32_t[] ,char8_t[] 和 char[] 不相同:
- char16_t[] : u"123"
- char32_t[] :U"123"
- char8_t[] :u8"123"
- char[] :L"123"
- wchar_t[] :"123"
可以看到,除了 char 都带前缀,以便区分。
注意,char8_t[] 和 char[] 不相同,如下代码会报错:
char8_t[] = "123";
char[] = u8"123"
注意:字符串字面量和字符串不一样, string("123") 是字符串,"123" 是字符串字面量,字符串字面量是 C 风格的,没有封装函数,下面的代码是错的。
cout << "hello" + "world" ;
string s = "hello world".substr(0, 5);
三、char_traits & allocator
char_traits
相信刚才大家已经看到了,char_traits 和 allocator,char_traits 主要用于提供字符之间的过程,如字串比较(c++20 后仅支持三路比较),移动,查找,源码在传送门的另一端。
allocator
而allocator ,即分配器,可以随意分配空间,使 vector 可以无限扩张,又不同于 new ,allocator 在前后可以均可扩张。实现在 <memory/alloctor.h> 头文件的 allocate 函数中:
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_Tp* allocate(size_t __n) {
if (__n > allocator_traits<allocator>::max_size(*this))
__throw_length_error("allocator<T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
if (__libcpp_is_constant_evaluated()) {
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
} else {
return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
}
四、高效使用
1.预先分配内存
string str;
str.reserve(100); // 预先分配足够内存,减少动态分配次数
2. 利用 char[]
与 string
互转
// C 风格字符串转换为 string
string Mystrintg = string("C++ String");
// string转换为 C 风格字符串
const char* MyCString = Mystring.c_str();
你学会了吗?