为什么
std::string
的大小由sizeof(std::string)
决定,产量为8
?8
,因为它必须有一个 int
(在我的机器上是 sizeof(int) == 8
)数据成员,用于在 O(1) 中给出 std::string::length()
和 std::string::size()
,并且可能有一个 char*
角色。
C++ 标准未指定
std::string
的实现。它仅描述类的行为。然而,我希望类中会有不止一个指针的信息价值。特别是:
它当然可以将所有这些存储在动态分配的位置中,因此占用与
char*
[在大多数架构中]完全相同的空间量。
事实上,查看我的 Linux 机器附带的 C++ 头文件,当您查看时,其实现非常清晰(根据注释,它是“C++11 之前的版本”,但我认为无论哪种方式都大致具有代表性):
size_type
length() const _GLIBCXX_NOEXCEPT
{ return _M_rep()->_M_length; }
然后按照以下步骤:
_Rep*
_M_rep() const _GLIBCXX_NOEXCEPT
{ return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
这又导致:
_CharT*
_M_data() const _GLIBCXX_NOEXCEPT
{ return _M_dataplus._M_p; }
这导致
// Data Members (private):
mutable _Alloc_hider _M_dataplus;
然后我们就可以:
struct _Alloc_hider : _Alloc
{
_Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPT
: _Alloc(__a), _M_p(__dat) { }
_CharT* _M_p; // The actual data.
};
有关字符串的实际数据是:
struct _Rep_base
{
size_type _M_length;
size_type _M_capacity;
_Atomic_word _M_refcount;
};
所以,这都是一个名为
_M_p
的简单指针,隐藏在几层吸气剂和一些转换中......
因为
std::string
存储的所有实现都是指向存储所有数据的堆的指针。