Newsgroup: it.comp.lang.c++
Titolo: string & ref counting

La documentazione delle STL di SGI contiene alcune note circa gli
inconvenienti di un'implementazione della classe string basata su
meccanismi di reference counting e condivisione del buffer (in sostanza, i
problemi di thread-safeness e quelli legati all'uso di reference a
caratteri o di iteratori).
Ero convinto che la maggior parte delle implementazioni facessero uso di
buffer condivisi, ma provando questa porzione di codice...
   string s("abc");
   string t;
   char & c = s[1] ;
   t = s;       
   c = 'z';     
   if (t[1] == 'z') {
        printf("wrong\n");
   } else {
        printf("right\n");
   }
...ho constatato che, salvo la classe string distribuita con una vecchia
versione del gcc cho ho a casa (2.7), tutte quelle che ho provato passano
il "test".
Questo significa che in generale si è abbandonato il metodo della
condivisione del buffer per l'implementazione delle classi string? 
Oppure si fa uso di meccanismi più sofisticati, come consentire la
condivisione sin quando non viene restituito un iteratore o un reference a
un carattere ?
Oppure mi sfugge qulcosa...?
Max
-- 
"Time flies like an arrow; fruit flies like a banana."

 un carattere ?
Non conosco tutte le implementazioni, ma questo e` cio` che ad
esempio fa la popolare implementazione Dinkumware (P.J.Plauger).
Penso di essere ampiamente entro i limiti della dottrina del "fair
use" citando 5 righe significative dalle 628 del suo XString...:
 iterator begin()
  {_Freeze();
  return (_Ptr); }
 const_iterator begin() const
  {return (_Ptr); }
Leggasi: se torno un iterator (ad es. begin()) che e` costante,
basta tornare _Ptr (poiche` e` undefined l'effetto se l'utente
modifica attraverso di esso); se non e` costante, prima di
poter tornare _Ptr devo applicare _Freeze(), cioe` garantire
che il puntatore sia congelato (non-condivisibile).
Alex

 
Ah, perfetto. In effetti, ora che mi sono andato a vedermela, anche
l'implementazione di basic_string nella mia versione dell'egcs, adotta una
soluzione analoga. As es:
 reference operator[] (size_type pos)
    { selfish (); return (*rep ())[pos]; }
Questo mi ha fatto pensare che anche una cosa innocua (nel senso che
non lascia in giro reference) come:
 
 char c =  s[ 1 ]; 
"congela" il buffer della string (se non è const), anche se ce ne sarebbe
bisogno.
Ehm, domanda da neofita: come posso usare la versione const di operator[]
con uno string non-const? Devo necessariamente passare da un const
reference ?
 const string & _s = s;
 char c =  _s[ 1 ]; 
Ci sono altri modi?


 wrote in message news:Pine.LNX.4.10.100011...@c64.comm2000.it...
    [snip]
 reference operator[] (size_type pos)
    { selfish (); return (*rep ())[pos]; }
Questo mi ha fatto pensare che anche una cosa innocua (nel senso che
non lascia in giro reference) come:
 char c =  s[ 1 ];
"congela" il buffer della string (se non è const), anche se ce ne sarebbe
bisogno.
Verissimo, purtroppo.
Ehm, domanda da neofita: come posso usare la versione const di operator[]
con uno string non-const? Devo necessariamente passare da un const
reference ?
 const string & _s = s;
 char c =  _s[ 1 ];
Ci sono altri modi?
Si`, tipo char c = const_cast<const string&>(s)[1], ma in effetti
passano da un const & e non mi pare siano migliori di questo.
Alex