在本机器上调用sizeof(string)的时候,答案为4
于是好奇之
typedef basic_string string;
* A string looks like this:
*
* @code
* [_Rep]
* _M_length
* [basic_string<char_type>] _M_capacity
* _M_dataplus _M_refcount
* _M_p ----------------> unnamed array of char_type
* @endcode
*
只有一个成员变量:
mutable _Alloc_hider _M_dataplus;
让我们看看这个成员变量
struct _Alloc_hider : _Alloc
{
_Alloc_hider(_CharT* __dat, const _Alloc& __a)
: _Alloc(__a), _M_p(__dat) { }
_CharT* _M_p; // The actual data.
};
看出来它只有一个char *指针
那么string的length呢?
size() const
{ return _M_rep()->_M_length; }
_M_rep() const
{ return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
_M_data() const
{ return _M_dataplus._M_p; }
_M_data()返回的是char *指针的位置,也就是说假设string a="abc"
*a.getData()是'a'
这样看来,在char *之前还有一段东西
base_string初始化的时候就预先分配了这个空间
basic_string()
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
: _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
static _Rep&
_S_empty_rep()
{ return _Rep::_S_empty_rep(); }
static _Rep&
_S_empty_rep()
{
// NB: Mild hack to avoid strict-aliasing warnings. Note that
// _S_empty_rep_storage is never modified and the punning should
// be reasonably safe in this case.
void* __p = reinterpret_cast<void*>(&_S_empty_rep_storage);
return *reinterpret_cast<_Rep*>(__p);
}
template<typename _CharT, typename _Traits, typename _Alloc>
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
(sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
sizeof(size_type)];
_CharT*
_M_refdata() throw()
{ return reinterpret_cast<_CharT*>(this + 1); }