C++程序员编码过程中经常会使用string(wstring)类,你是否思考过它的内部实现细节。比如这个类的迭代器是如何实现的?对象占多少字节的内存空间?内部有没有虚函数?内存是如何分配的?构造和析构的成本有多大?笔者综合这两天阅读的源代码及个人理解简要介绍之,错误的地方望读者指出。
首先看看string和wstring类的定义:
typedef basic_string<char, char_traits<char>, allocator<char> > string;
typedef basic_string<wchar_t, char_traits<wchar_t> allocator<wchar_t> > wstring;
从这个定义可以看出string和wstring分别是模板类basic_string对char和wchar_t的特化。
再看看basic_string类的继承关系(类方法未列出):
最顶层的类是_Container_base,它也是STL容器的基类,Debug下包含一个_Iterator_base*的成员,指向容器的最开始的元素,这样就能遍历容器了,并定义了了两个函数
void _Orphan_all() const; // orphan all iterators
void _Swap_all(_Container_base_secure&) const; // swaps all iterators
Release下_Container_base只是一个空的类。
_String_base类没有数据成员,只定义了异常处理的三个函数:
static void _Xlen(); // report a length_error
static void _Xran(); // report an out_of_range error
static void _Xinvarg();
_String_val包含一个alloctor的对象,这个类也非常简单,除了构造函数没有定义其它函数。
上面三个基类都定义得很简单,而basic_string类的实现非常复杂。不过它的设计和大多数标准库一样,把复杂的功能分成几部分去实现,充分体现了模块的低耦合。
迭代器有关的操作交给_String_iterator类去实现,元素相关的操作交给char_traits类去实现,内存分配交给allocator类去实现。
_String_iterator类的继承关系如下图:











