Стандарт STL не требует от std::string для пересчета. Но на самом деле большинство С++ реализации предоставляют обновленные, скопированные строки, позволяющие вам проходить строка по значению как примитивный тип. Также эти реализации (по крайней мере, g++) используют атомных операций, делающих эти строки незакрепленными и безопасными по потоку.
Простой тест показывает семантику copy-on-write:
#include <iostream>
#include <string>
using namespace std;
void foo(string s)
{
cout<<(void*)s.c_str()<<endl;
string ss=s;
cout<<(void*)ss.c_str()<<endl;
char p=ss[0];
cout<<(void*)ss.c_str()<<endl;
}
int main()
{
string s="coocko";
cout<<(void*)s.c_str()<<endl;
foo(s);
cout<<(void*)s.c_str()<<endl;
}
Только два адреса печатаются точно после использования непостоянного члена.
Я протестировал этот код с помощью компилятора HP, GCC и Intel и получил аналогичные результаты - строки работать как контейнеры для копирования на запись.
С другой стороны, VС++ 2005 ясно показывает, что каждая строка полностью скопирована.
Почему?
Я знаю, что в VС++ 6.0 произошла ошибка, у которой была небезобезопасная реализация подсчет ссылок, вызвавший случайные программные судороги. Это причина? Они просто боятся использовать ref-counting больше, даже это обычная практика? Они предпочитают не использовать ref-counting для решения проблемы?
Спасибо