c++ 站在STL的角度重新看 string——字符串详解

目录

一、定义

二、字符串字面量

三、char_traits & allocator

char_traits

allocator

一、定义

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();

你学会了吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值