C++ std::string的引用计数
我正在看C++ std::string的引用计数,c++,string,g++,stdstring,reference-counting,C++,String,G++,Stdstring,Reference Counting,我正在看basic_string(与g++4.2.1捆绑在一起)的代码。复制构造函数使用grab()函数“获取”字符串的副本(增加其引用计数): 只有当两个字符串的分配器相同时,才会增加引用计数——这是有意义的。但是,复制构造函数是: basic_string(const basic_string& __str) : _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), __str.get_alloca
basic_string
(与g++4.2.1捆绑在一起)的代码。复制构造函数使用grab()
函数“获取”字符串的副本(增加其引用计数):
只有当两个字符串的分配器相同时,才会增加引用计数——这是有意义的。但是,复制构造函数是:
basic_string(const basic_string& __str)
: _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), __str.get_allocator()),
__str.get_allocator())
{ }
传递给\u M_grab()
的第一个分配器是第二个分配器的副本。为什么?allocator
的operator==()
可能返回false的唯一方法是用户使用自定义分配器。然而,即使这是真的,您也会认为复制的分配器会与其原始分配器进行比较,对吗?因此:
是的,
\u M\u grab()
用于另一个位置:分配。在这种情况下,传递给\u M\u grab()
的分配器是不同的。好的但是似乎仍然没有理由复制构造函数,然后比较构造函数中string
的分配器。我知道关于GCC团队的推理,但以下是我的假设:
\u M_grab
中,它不知道在这种特殊情况下,一个参数是从另一个参数复制构建的\u M_grab
也从assign
调用,其中两个字符串可能具有不同的分配器也没有特别好的理由实现两个几乎相同版本的
\u M_grab()
,以避免不必要的比较,这(对于大多数分配器)无论如何都会在编译时发生。也许你认为这样的微观优化是可取的;显然,这段代码的作者没有看到。我在这里看不到其余的代码,但真正的实用程序是否可能是在从其他地方调用\u m_grab()
时使用的,而在这里,完成分配器的额外副本只是为了查看分配器是否都是副本可构造的,以及副本比较是否相等?显然,如果第一个不正确,调用甚至不会编译,但如果后一个不正确,资源管理仍会正常运行。@seh:您的“后一个”案例有一定道理,但我想不出一个副本构造的分配器与原始分配器相比不相等的用例,这似乎是一个非常奇怪的案例。然而,这可能并不罕见,因为这个字符串类的作者考虑到了这一点。所以我很好奇这种情况可能是什么。如果#3总是正确的,那么为什么还要费心去复制它呢?为什么不把这两个参数的u str.get_allocator()传递给_M_grab()?@Paul:你说得对;看起来显式副本是不必要的,但无害的get_allocator()
无论如何都会返回一个副本。我的问题更多的是明显不必要的副本构造,而不是比较(您在回复我的评论时提到了这一点);因此,您以后的“更新”似乎有点不合逻辑。
basic_string(const basic_string& __str)
: _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), __str.get_allocator()),
__str.get_allocator())
{ }