std :: string的引用计数

时间:2010-07-28 16:03:01

标签: c++ string g++ stdstring reference-counting

我正在查看basic_string的代码(与g ++ 4.2.1捆绑在一起)。复制构造函数使用grab()函数来“获取”字符串的副本(增加其引用计数):

_CharT* _M_grab( const _Alloc& __alloc1, const _Alloc& __alloc2 ) {
  return (!_M_is_leaked() && __alloc1 == __alloc2) ? _M_refcopy() : _M_clone(__alloc1);
}

只有当两个字符串的分配器相同时才会增加引用计数 - 这是有意义的。但是,复制构造函数是:

basic_string(const basic_string& __str)
: _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), __str.get_allocator()),
              __str.get_allocator())
{ }

传递给_M_grab()的第一个分配器是第二个分配器的副本。为什么? operator==() allocator可能返回false的唯一方法是用户是否使用自定义分配器。但是,即使这是真的,你也会认为复制的分配器与原来的分配器相当,对吧?所以:

  1. 为什么要比较分配器?
  2. 为什么要复制构造一个分配器并将副本与原始文件进行比较?
  3. 将副本与原始副本进行比较会返回false是什么用例?
  4. 更新

    是的,_M_grab()用于另一个地方:用于分配。在这种情况下,传递给_M_grab() 的分配器与不同。精细。但似乎没有理由在{em>构造函数中复制构造然后比较string中的分配器。

2 个答案:

答案 0 :(得分:1)

我知道关于海湾合作委员会小组的推理的拉链,但这是我的假设:

  1. 进行调试?分配器必须是相同的。

  2. 所以它可以重用_M_grab()?

  3. 永远不应该发生?

答案 1 :(得分:1)

  1. 如果从一个分配的对象可以与另一个分开,则分配器比较相等。如果是这种情况,则两个字符串可以共享对同一分配器的引用;否则,每个人都需要自己的分配器。

  2. 比较发生在_M_grab内,它不知道在这种特殊情况下,一个参数是从另一个参数复制构造的。 _M_grab也是从assign调用的,其中两个字符串可能有不同的分配器。

  3. 分配器应始终与其自身的副本进行比较。

  4. <强>更新

      

    但似乎没有理由复制构造,然后在构造函数中比较分配器的字符串。

    没有特别好的理由来实现两个几乎完全相同的_M_grab()版本以避免不必要的比较,这对于大多数分配器来说无论如何都会在编译时发生。也许你认为这样的微优化是可取的;显然这段代码的作者没有。