30 votes

À propos de l'utilisation de new et delete, et des conseils de Stroustrup

À propos de l'utilisation de nouveaux et de les supprimer et de Stroustrup conseils...

Il dit quelque chose comme (mais pas exactement, c'est à partir de mes notes de son livre):

Une règle de base est que, new appartient à des constructeurs et des opérations similaires, delete appartient à des destructeurs. En outre, new est souvent utilisé dans les arguments de la ressource poignées. Sinon, évitez d'utiliser des new et delete, l'utilisation des ressources poignées (des pointeurs intelligents) à la place.

Je me demandais si le plus connu des gens avec C++11 ont vraiment appliquée ou non.

Mon impression de cette a été, wow, cela semble vraiment cool, la règle à suivre. Mais alors je suis méfiant, comme pour toute règle générale. À la fin de la journée vous allez vous retrouver en utilisant de nouveaux et de les supprimer si nécessaire. Mais peut-être cette règle est un bon guide, je ne sais pas.

48voto

Joseph Mansfield Points 59346

C'est une grande règle. En fait, vous pouvez éviter d'utiliser new dans les arguments de pointeurs intelligents par l'aide de la make_ fonctions. Par exemple, au lieu de:

std::shared_ptr<int> p(new int(5));

Vous pouvez souvent faire:

auto p = std::make_shared<int>(5);

Cela a aussi l'avantage d'être plus exception coffre-fort. Alors qu'un std::make_unique n'existe pas encore, il est prévu de faire son chemin dans C++14 (il est déjà dans le projet de travail). Si vous le voulez maintenant, il y a quelques implémentations existantes.

Vous pouvez aller plus loin et même éviter d'utiliser des new et delete dans les constructeurs et les destructeurs. Si vous avez toujours envelopper les objets alloués dynamiquement dans des pointeurs intelligents, même quand ils sont membres de la classe, vous n'aurez pas besoin de gérer votre propre mémoire à tous. Voir la Règle de Zéro. L'idée est que ce n'est pas de la responsabilité de votre classe pour mettre en œuvre toute forme de propriété sémantique (SRP) - c'est ce que les pointeurs intelligents sont pour. Alors vous, théoriquement, ne jamais avoir à écrire de copier/déplacer des constructeurs, copier/déplacer des opérateurs d'affectation ou destructeurs, parce que les fonctions définies implicitement sera généralement faire la bonne chose.

14voto

Dietmar Kühl Points 70604

Ressemble plus à un sondage qu'une question, mais ici, il va: en application du code général je n'ai pas utiliser new à tous. Grâce à nos directives de codage, le code n'utiliser de pointeur, mais aucun de ces "nu" pointeurs est en fait le transfert de propriété. Tous les objets sont détenus par un autre objet.

Pour être juste, lorsque les objets doivent être affectées à l'attribution utilise généralement quelque chose de moralement équivalent à std::make_shared<T>(...) qui, parfois, ne présentent que dans le code de l'application. L'une des principales raisons à cela plutôt complète absence d' new (ou similaire), c'est que les objets sont généralement alloués à l'aide de stateful allocateurs et de ne pas le faire par l'intermédiaire d'un gestionnaire de ressources qui se passe réellement à être assez compliqué. Ainsi, il y a peu de place pour direct de l'allocation de mémoire à l'aide de new ou d'un placement version de celui-ci dans le code de l'application.

Dans une infrastructure de code, en particulier lors de la création de conteneurs personnalisés, la situation est légèrement différente: il s'agit de la mémoire allouée (à partir de allocateurs et initialisé à l'aide de placement new) il y a des. Cependant, même là, le résultat de l'allocation de la mémoire et de l'initialisation des objets est immédiatement transmise aux gestionnaires de ressources. Fondamentalement, je ne peux pas faire face explicite de la gestion des ressources et à l'aide de gestionnaires de ressources juste reliefs m'des travaux nécessaires.

3voto

La façon dont je pense, c'est que toutes les ressources doivent être la propriété de quelque chose. Le propriétaire est la personne qui est responsable du nettoyage. Habituellement, ce propriétaire est un pointeur intelligent d'une certaine sorte, mais même std::vector est un propriétaire d'une ressource: le bloc de mémoire qui stocke il est limitrophe des éléments. Ce conseil ne vaut pas seulement pour la mémoire, mais toutes les ressources, telles que les descripteurs de fichiers, base de données gère, mutex, etc...

Lorsque vous appelez nouveau et supprimer manuellement dans une partie de votre code qui n'est pas une classe wrapper, vous le programmeur devenir le propriétaire de la ressource. La propriété s'accompagne de la responsabilité de nettoyage après vous. Maintenant, vous et l'ensemble de la maintenance des programmeurs qui viennent après vous avoir pour s'assurer que tous les chemins de code après la nouvelle, éventuellement, conduire à une suppression. Même pour de simples fonctions, cela est très facile de se tromper. Avec des exceptions, presque impossible à moins que vous soigneusement envelopper le tout dans des blocs try catch, entraînant les performances d'exécution des peines et de polluer votre code supplémentaire étendues et inutile logique d'exception. Enfin, même si vous ne l'obtenez à droite, vous venez de perdre votre temps à faire ce travail fastidieux de la gestion des ressources. Le compilateur est l'outil qui peut faire ce travail pour vous, utilisez-le.

La pire situation est lorsque certains sous-système alloue une ressource, elle est passée autour de l'application, et quelques autres, loin du sous-système de la libère. Le nombre de chemins de code possible dans cette situation est insoluble. Il est très difficile, si pas impossible pour un être humain de comprendre et de confiance. À mon avis, ce style de programmation est difficile à maintenir. Combien de projets C avez-vous travaillé dans le passé qui sont truffées d'erreurs de mémoire, en particulier sur rarement, voire jamais exécuté erreur de manipulation des chemins? J'ai fait affaire avec plus de soins, je verrai plus.

C a manuel de gestion de la mémoire, Java et d'autres ont la collecte des ordures. C++ a RAII. Il est aussi efficace comme le C et le et presque aussi sûr que la collecte des ordures.

Ma règle est simple, si vous trouvez vous-même manuellement le nettoyage de toute ressource, vous avez écrit un bug.

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