65 votes

chaînes immuables vs std::string

Je me suis récemment renseigné sur les chaînes de caractères immuables. Pourquoi les chaînes de caractères ne peuvent-elles pas être mutables en Java et .NET ? y Pourquoi .NET String est immuable ? ainsi que des informations sur les raisons pour lesquelles D choisit des chaînes immuables. Il semble y avoir de nombreux avantages.

  • trivialement thread safe
  • plus sûr
  • plus efficace en termes de mémoire dans la plupart des cas d'utilisation.
  • des sous-chaînes bon marché (tokenizing et slicing)

Sans compter que la plupart des nouveaux langages ont des chaînes immuables, D2.0, Java, C#, Python, etc.

Le C++ bénéficierait-il de chaînes de caractères immuables ?

Est-il possible d'implémenter une classe de chaîne immuable en c++ (ou c++0x) qui aurait tous ces avantages ?


mettre à jour :

Il existe deux tentatives de chaînes de caractères immuables const_string y fix_str . Aucun des deux n'a été mis à jour depuis une demi-décennie. Sont-ils au moins utilisés ? Pourquoi const_string ne s'est jamais retrouvé dans boost ?

42 votes

Un argument très élaboré et convaincant que vous avez fait là, BlueRaja.

6 votes

Eh bien, BlueRaja n'a pas vraiment fait un argument, comme vous l'avez tous si clairement souligné. Mais il pourrait avoir raison, en ce sens que le C++ est peut-être trop un langage hybride pour que les tentatives puristes d'une chaîne de caractères immuable trouvent leur place. Cela en dit plus sur la culture C++ que sur le langage lui-même, bien sûr.

5 votes

Objection ! La chaîne de caractères de Ruby n'est pas immuable !

49voto

yoco Points 676

J'ai trouvé que la plupart des gens dans ce fil de discussion ne comprennent pas vraiment ce que immutable_string est. Il ne s'agit pas seulement de la constance. Le pouvoir réel de immutable_string est la performance (même dans un programme à un seul fil) et l'utilisation de la mémoire.

Imaginez que, si toutes les chaînes de caractères sont immuables, et que toutes les chaînes de caractères sont implémentées comme suit

class string {
    char* _head ;
    size_t _len ;
} ;

Comment mettre en œuvre une opération de sous-stratégie ? Nous n'avons pas besoin de copier un caractère. Tout ce que nous avons à faire, c'est d'assigner le _head et le _len . La sous-chaîne partage alors le même segment de mémoire que la chaîne source.

Bien sûr, nous ne pouvons pas vraiment mettre en œuvre une chaîne immuable uniquement avec les deux membres de données. L'implémentation réelle pourrait avoir besoin d'un bloc de mémoire compté par référence (ou pondéré par la mouche). Comme ceci

class immutable_string {
    boost::fly_weight<std::string> _s ;
    char* _head ;
    size_t _len ;
} ;

La mémoire et les performances seraient meilleures que celles de la chaîne traditionnelle dans la plupart des cas, surtout si vous savez ce que vous faites.

Bien sûr, le C++ peut bénéficier de chaînes immuables, et il est agréable d'en avoir une. J'ai vérifié le boost::const_string et le fix_str mentionné par Cubbi. Ce devrait être ce dont je parle.

25voto

Comme une opinion :

  • Oui, j'aimerais bien une bibliothèque de chaînes immuables pour le C++.
  • Non, je ne voudrais pas que std::string soit immuable.

Cela vaut-il vraiment la peine de le faire (en tant que fonctionnalité de la bibliothèque standard) ? Je dirais que non. L'utilisation de const vous donne des chaînes localement immuables, et la nature fondamentale des langages de programmation de systèmes signifie que vous avez vraiment besoin de chaînes mutables.

9voto

Notinlist Points 3060

Ma conclusion est que le C++ n'a pas besoin du modèle immuable parce qu'il a la sémantique const.

En Java, si vous avez un Person et vous retournez la classe String name de la personne avec le getName() votre seule protection est le modèle immuable. S'il n'était pas là, vous devriez clone() vos chaînes de caractères toute la nuit et le jour (comme vous devez le faire avec les membres de données qui ne sont pas des objets de valeur typiques, mais qui doivent quand même être protégés).

En C++, vous avez const std::string& getName() const . Vous pouvez donc écrire SomeFunction(person.getName()) où c'est comme void SomeFunction(const std::string& subject) .

  • Aucune copie ne s'est produite
  • Si quelqu'un veut copier, il est libre de le faire.
  • La technique s'applique à tous les types de données, pas seulement aux chaînes de caractères.

4 votes

Correction ! Les chaînes immuables peuvent être utiles dans les programmes multithreads car elles n'ont aucune incidence sur la gestion de la concurrence. Et la plupart du temps, vous ne modifiez pas vos chaînes de caractères, vous les remplacez simplement.

3voto

peterchen Points 21792

Je ne pense pas qu'il y ait une réponse définitive ici. C'est subjectif - si ce n'est par goût personnel, c'est au moins en raison du type de code avec lequel on travaille le plus souvent. (Tout de même, une question intéressante).

Les chaînes immuables sont excellentes lorsque la mémoire est bon marché - ce n'était pas le cas lorsque le C++ a été développé, et ce n'est pas le cas sur toutes les plateformes ciblées par le C++. (Par contre, sur les plateformes plus limitées, le C semble beaucoup plus courant que le C++, donc cet argument est faible).

Vous pouvez créer une classe de chaînes immuables en C++, et la rendre largement compatible avec std::string -Mais vous perdrez toujours du terrain par rapport à une classe de chaîne de caractères intégrée, dotée d'optimisations et de fonctionnalités de langage spécifiques.

std::string est le meilleur standard que nous recevons, donc je ne voudrais pas que l'on y touche. Je l'utilise très rarement, cependant ; std::string présente trop d'inconvénients de mon point de vue .

2 votes

Si std::string est la meilleure chaîne standard, mais vous l'utilisez très rarement en raison de son trop d'inconvénients ce qui DO que vous utilisez ?

3 votes

CString (ne me tuez pas, s'il vous plaît) en raison de >10 ans de bibliothèques accumulées, d'une meilleure interopérabilité de l'API native (y compris les conversions wchar_t / char). À l'époque, le copy-on-write bien défini était également un avantage par rapport au manque de garanties de performance de std::string.

0 votes

@peterchen Le CString dans MFC ou WTL ?

3voto

Cubbi Points 25339

Vous n'êtes certainement pas la seule personne à penser cela. En fait, il y a const_string La bibliothèque de Maxim Yegorushkin, qui semble avoir été écrite dans l'optique d'une inclusion dans le boost. Et voici une bibliothèque un peu plus récente, fix_str par Roland Pibinger. Je ne suis pas sûr que l'internage complet des chaînes de caractères au moment de l'exécution soit très délicat, mais la plupart des avantages sont réalisables lorsque cela est nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X