更多精彩内容,请关注微信公众号:后端技术小屋c++
从定义可知, string
实际上是base_string
的特化类,string
使用默认的内存分配器__STL_DEFAULT_ALLOCATOR(_CharT)
。后端
template <class _CharT, class _Traits = char_traits<_CharT>, class _Alloc = __STL_DEFAULT_ALLOCATOR(_CharT) > class basic_string; typedef basic_string<char> string;
而traits
是c++中一个重要特性,使用traits
可在编译器肯定类型相关的信息。好比某个模板参数是否为整形。string
中默认的模板参数_Traits
为char_traits<_CharT>
, 定义以下api
template <class _CharT> class char_traits : public __char_traits_base<_CharT, _CharT> {}
能够看到char_traits<_CharT>
继承自__char_traits_base<_CharT, _CharT>
,其中定义了字符类型_CharT
的各类操做,供basic_string
方法调用:例如basic_string::operator=
中调用了__char_traits_base::length
,basic_string::clear
中调用了__char_traits_base::assign
数组
如下是一些常见的字符操做微信
memmove
复制字符数组A到Bmemcpy
复制字符数组A到B(memmove
和memcpy
做用类似,都用于字节数组的复制,可是后者不容许内存区域有重叠)static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; } static bool eq(const _CharT& __c1, const _CharT& __c2) { return __c1 == __c2; } static bool lt(const _CharT& __c1, const _CharT& __c2) { return __c1 < __c2; }
string
的内存结构相似于vector
,由一段连续的内存缓冲区组成,_M_start
为已用缓冲区的首地址,_M_finish
为已用缓冲区的尾地址,_M_end_of_storage
为空闲缓冲区的尾地址, 以下图所示数据结构
由于string的API和vector相似,所以方法也相似, 此处略过源码分析
clear
时,string占用的内存并不会释放,只是_M_finish = _M_start
而已。所以若是须要释放string内存,可执行`str.swap(string())``reserve(len)
时,会从新分配1+max(size()+len)
大小的内存缓冲区, 并将旧缓冲区数据复制到新缓冲区,开销比较大。所以不要随便执行reserve
,以避免内存的从新分配复制。当肯定某个对象的最大长度时,可以使用reserve
预分配足够大的内存,可避免后续字符串增加致使内存的从新分配复制。推荐阅读code
更多精彩内容,请扫码关注微信公众号:后端技术小屋。若是以为文章对你有帮助的话,请多多分享、转发、在看。
对象