“有效STL”中的Scott Meyer说,在决定使用哪种数据结构时要考虑的一件事是容器是否使用引用计数.他说这种方法存在一些行为异常现象.
它们中有哪些是什么?为什么像’string’和’rope’这样的容器有异常行为?
解决方法
正如其他人所说,典型的例子是std :: string.除了锁定多线程程序的性能问题外,引用计数字符串还存在无线程问题.想象一下:
string s = "hello"; string t = s; // s and t share data char &c = t[0]; // copy made here,since t is non-const
问题是非const运算符[]必须复制字符串,如果它是共享的,因为返回的引用可以在以后用于修改字符串(您可以将它分配给非引用字符,但运算符[]不知道它应该表现得有什么不同).另一方面,const运算符[]应该避免复制,因为这将消除引用计数的所有好处(这意味着你总是在实践中复制).
const char &get_first(const string &s) { return s[0]; // no copy,s is const } string s = "hello"; string t = s; // s and t share data const char &c1 = get_first(t); // no copy made here const char &c2 = t[0]; // copy made,since t is non-const // c1 just got invalidated (in fact,it's pointing at s[0],not t[0]). s[0] = 'X'; printf("%c,%c\n",c1,c2); // outputs "X,h"
正如您所看到的,这种区别令人困惑,可能会导致意外行为.
这是一篇关于写时复制语义及其对性能的影响的旧文章:http://www.gotw.ca/gotw/045.htm.
这是一个提议,有动机将std :: string更改为不在C 11标准中引用计数:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2534.html.这就是上面的例子所基于的内容.