9
votes

Quand avez-vous surchargé un opérateur neuf?

Dupliqué possible:
Toute raison de surcharger global nouveau et Supprimer?

Dans quels cas est-il parfaitement logique de surcharger opérateur neuf ?

Je vous ai entendu le faire dans une classe qui est très souvent allouée à l'aide de Nouveau . Pouvez-vous donner un exemple?

et y a-t-il d'autres cas où vous voudriez surcharger opérateur nouveau ?

Mise à jour: Merci pour toutes les réponses jusqu'à présent. Quelqu'un pourrait-il donner un exemple de code court? C'est ce que je voulais dire quand j'ai demandé à propos d'un exemple ci-dessus. Quelque chose comme: Voici une petite classe de jouets, et voici un opérateur NOUVEAU pour cette classe.


5 commentaires

Ne pas essayer d'être une douche, mais des réponses utiles auraient été trouvées avec une recherche: Stackoverflow.com/Questtions/1152511/...


@Skurmedel: Mais celui-ci ne concerne que l'opérateur mondial neuf (et supprimez). Je demandais de surcharger l'opérateur Nouveau en général, par exemple. dans une classe.


Je ne vois pas pourquoi les raisons seraient vraiment différentes, autres que les différentes cales.


Pourriez-vous s'il vous plaît rouvrir, car cette question a vraiment une orientation différente de celle indiquée comme dupliquée: c'est vraiment pourquoi vous ajouteriez un tel opérateur à une classe et à quoi ressemblerait.


Je n'ai pas voté pour fermer; Je ne peux pas. Peut-être pourriez-vous attirer l'attention d'un modérateur avec le bouton drapeau.


4 Réponses :


4
votes

Le meilleur cas que j'ai trouvé était d'empêcher la fragmentation de tas en fournissant plusieurs tas de blocs de taille fixe. C'est-à-dire que vous créez un tas composé entièrement de blocs de 4 octets, un autre avec 8 blocs d'octets, etc.

Cela fonctionne mieux que le tas de "tout en un" par défaut, car vous pouvez réutiliser un bloc, sachant que votre allocation ira dans le premier bloc libre, sans avoir à vérifier ou à marcher sur le tas à la recherche d'un espace libre qui est le droit Taille.

L'inconvénient est que vous utilisez plus de mémoire, si vous avez un tas de 4 octets et un tas de 8 octets, et souhaitez allouer 6 octets .. Vous allez devoir le mettre dans le 8 octet tas, gaspillage de 2 octets. De nos jours, ce n'est guère un problème (surtout lorsque vous envisagez les frais généraux des systèmes alternatifs)

Vous pouvez l'optimiser, si vous avez beaucoup d'allocations à faire, vous pouvez créer un tas de cette taille exacte. Personnellement, je pense que gaspiller quelques octets n'est pas un problème (par exemple, vous allociez beaucoup de 7 octets, l'utilisation d'un tas de 8 octets n'est pas une grande difficulté à un problème).

Nous l'avons fait pour un système de très haute performance et cela a permis de réduire considérablement nos problèmes de performance en raison de la fragmentation des allocations et des tas de tas et était de manière dramatiquement transparente du reste du code.


4 commentaires

Je ne sais pas quel système d'exploitation vous avez essayé. Mais le gestionnaire de Windows Heap utilise déjà cette approche. Je serais surpris si d'autres ne le font pas de cette façon.


La gestion de la mémoire C ++ est optimisée pour les petits blocs qui apparaissent et disparaissent rapidement. Essayer de ré-optimiser, il ne fonctionnera probablement pas pour votre programmeur moyen. De plus, la description que vous fournissez ci-dessus est un schéma très courant utilisé par presque tous les systèmes de gestion de la mémoire. La ré-mise en œuvre ne fournira aucun béniifit.


Jusqu'à quelle taille le travail d'optimisation de l'allocation de blocs est-il en général? Je suis intéressé par les versions récentes de GCC en particulier.


Trouvé ma réponse (pour Linux) dans ptmalloc -> malloc.c. Il dit "pour les petites requêtes (<= 64 octets par défaut), il s'agit d'un allocateur de mise en cache qui maintient des pools de morceaux recyclés rapidement."



0
votes

Vous le faites dans les cas où vous souhaitez contrôler l'allocation de la mémoire pour un objet. Comme lorsque vous avez de petits objets qui ne seraient attribués que sur le tas, vous pouvez allouer de l'espace pour des objets 1K et utiliser le nouvel opérateur pour allouer d'abord les objets 1K, et utiliser l'espace jusqu'à ce qu'il soit utilisé.


0 commentaires

3
votes

Certaines raisons de surcharger l'opérateur Nouveau

  1. Suivi et profilage de la mémoire et détecter les fuites de mémoire
  2. Pour créer des pools d'objets (par exemple pour un système de particules) pour optimiser l'utilisation de la mémoire

0 commentaires

12
votes

Certaines raisons de surcharger par classe
1. Instrumentation I.e Tracking Allocs, Sentiers d'audit sur l'appelant, tels que le fichier, la ligne, la pile.
2. Routines d'allocation optimisées I.E Pools de mémoire, allocateurs de blocs fixes.
3. Allocators spécialisés I.e Allocator contigu pour 'Allouer une fois sur les objets de démarrage' - fréquemment utilisé dans la programmation des jeux pour la mémoire qui doit persister pour tout le jeu, etc. 4. Alignement. Ceci est un grand sur la plupart des systèmes non de bureau, en particulier dans les consoles de jeux où vous avez souvent besoin d'allouer par ex. Limites de 16 octets
5. Magasins de mémoire spécialisés (à nouveau surtout des systèmes non-desktop) tels que la mémoire non cacheable ou la mémoire non locale


0 commentaires