【发布时间】:2010-07-28 16:03:01
【问题描述】:
我正在查看 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==() for allocator 可能返回 false 的唯一方法是用户使用自定义分配器。但是,即使这是真的,您也会认为复制的分配器将与其原始分配器进行比较,对吗?所以:
- 为什么要比较分配器?
- 为什么要复制构造分配器并将副本与原始文件进行比较?
- 将副本与其原件进行比较会返回 false 的用例是什么?
更新
是的,_M_grab() 用于另一个地方:分配。在这种情况下,传递给_M_grab() 的分配器是不同的。美好的。但似乎仍然没有理由同时复制构造,然后比较 string 的 构造函数 中的分配器。
【问题讨论】:
-
我在这里看不到其余的代码,但是当
_M_grab()从其他地方被调用时,真正的实用程序是否可能是,这里分配器的额外副本是只是为了看看分配器是否都是可复制的以及副本是否比较相等?显然,如果第一个不正确,调用甚至不会编译,但如果后者不正确,资源管理仍然会正常运行。 -
@seh:您的“后一种”情况是有道理的,但我想不出一个用例,其中复制构造的分配器与原始分配器相比 - 似乎非常奇怪的情况。但是,这可能并不罕见,因为这个字符串类的作者考虑了它。所以我很好奇这种情况可能是什么。
标签: c++ string g++ stdstring reference-counting