8
votes

dois-je détruire une chaîne en C ++

Si j'ai une chaîne dans une classe, la mémoire est allouée. Dois-je détruire la corde dans le destructeur? E.G.

class A {
  string Test;
  A() {
    Test = "hello world";
  }

  A(string &name) {
    Test = name;
  }

  ~A() {
    // do I have to destroy the string here?
  }
}


3 commentaires

Dans votre exemple, string résolve à :: std :: string ?


La chose intéressante (pour moi) se trouve dans le destructeur. C ++ garantit-il que les objets membres sont destructés après l'appel du constructeur de l'objet parent? Puis-je empêcher cela? (Juste hors de curiosité; peut-être que vous pouvez citer les sections pertinentes de la norme C ++.)


C ++ garantit que vos membres de classe seront détruits dans l'ordre opposé à partir desquels ils ont été construits (qui est l'ordre dans lequel ils ont été déclarés). Une explication plus lisible que la norme C ++: msdn.microsoft. COM / EN-US / Bibliothèque / 8183ZF3x (vs.80) .aspx


4 Réponses :


11
votes

Oui, STD :: Les ressources de la chaîne sont nettoyées automatiquement. Les chaînes et les conteneurs standard allouent / négocient pour vous. Cependant, un conteneur de pointeurs ne libère pas ce que ces indicateurs pointaient. Vous devez vous en protéger vous-même.


10 commentaires

À droite. C'est la différence entre la pile et le tas. +1


Merci, (c'était rapide), vous avez préemptéré mon prochain queston sur les conteneurs. Existe-t-il une façon de définir les conteneurs afin qu'ils libèrent automatiquement ce qu'ils contiennent? par exemple. Delphi (où je me déplace de) Vous pouvez définir un drapeau propriétaire dans une liste et détruire automatiquement les objets contenus.


Vous voudrez peut-être jeter un coup d'œil à des pointeurs intelligents - c'est fondamentalement un objet qui émule la fonctionnalité du pointeur qui sera supprimée par lui-même car elle laisse une portée. en.wikipedia.org/wiki/smart_pointer


J'aime boost :: partagé_ptr moi-même, mais je ne fais pas grand chose avec multithreading. Les pointeurs intelligents en général sont assez apifs. RECHERCHEZ RAII. Très spiffy en effet.


J'ai regardé les pointeurs intelligents et je vais éventuellement les utiliser - mais c'est probablement à gros saut à l'époque - Baby Steps :-) Merci encore à tous


@Ellusif The std :: String Peut allouer la mémoire de tas, et celle-ci aussi est nettoyée par ~ std :: string :: string () . PS: Je recommande d'éviter l'espace de noms "utilise". Lorsque le seul espace de noms que vous utilisez est "std", ce n'est pas une si grosse affaire ... mais lorsque vous commencez à jeter plus, il devient un véritable nid de rats, à moins que vous sachiez quelle classe est de savoir où.


@Markstorer, non, les pointeurs des chaînes sont disposés par des destructeurs de string quand ils sortent de la portée


@datdinhquoc std :: vecteur : pas de problème. std :: vecteur fuite, sauf si vous iTerez-le à travers le conteneur et supprimez ces pointeurs (à condition qu'ils soient de nouveaux en premier lieu ... s'ils pointe Pour un tas de cordes de pile que vous savez ne pas sortir de la portée de la vie du conteneur, ce n'est toujours pas un problème). Alors pourquoi toujours utiliser un conteneur de pointeurs? Efficacité. Il est moins cher de transmettre un pointeur de 64 bits qu'il ne consiste pas à copier «la guerre et la paix». Facile vs efficace. Temps de programmeur VS Ressources système. Demandez à un PM: le temps de programmeur est une ressource.


@Markstorer euh oui, hm, cordes à l'intérieur des vecteurs et des cartes


Contexte culturel à mon précédent commentaire: "Guerre et paix" est le titre d'un livre de plus de 1400 pages, plutôt qu'une chaîne littérale.



3
votes

Non. Le destructeur de la chaîne sera appelé une fois qu'une instance de A dépasse de la portée.


0 commentaires

3
votes

Vous ne créez pas de pointeur sur la chaîne, le test sera donc attribué sur la pile (en supposant que l'objet A a été attribué à la pile). Ainsi, quand il laisse une portée, il sera traité automatiquement. Si le test était un pointeur, il serait alloué sur le tas et vous auriez besoin de la supprimer dans le destructeur


2 commentaires

Nous ne savons pas que "test" sera sur la pile. Mais tu as raison sinon.


Vrai, pour une raison quelconque, elle n'avait pas franchi mon esprit que toute la classe a peut-être été allouée sur le tas dans lequel le test de cas serait sur le tas, peu importe.



0
votes

Vous nettoyez votre désordre et la bibliothèque standard nettoie son désordre. La mémoire qu'un STD :: String alloue est son désordre.

Le comportement par défaut pour un destructeur consiste à appeler des destructeurs sur chaque base et membre de données. Votre chaîne est un élément de données, son destructeur est donc appelé. Son destructeur fait tout ce qui doit être fait ici, il n'ya donc plus besoin (et il serait en fait très faux) de nettoyer quoi que ce soit ici que si vous aviez la chaîne en tant que variable locale en main ().


0 commentaires