2010-11-09 3 views
27

Supposons que je doive surcharger global ::operator new()for storing extra data with each allocated object. Donc, fondamentalement, il marcherait ainsi:Comment appeler l'original "operator new" si je l'ai surchargé?

  • pour chaque appel à ::operator new() mondial, il prendra la taille de l'objet passé et ajouter la taille des données supplémentaires
  • il allouer un bloc de mémoire de taille déduite au précédent étape
  • il compensera le pointeur sur la partie du bloc non occupé avec des données supplémentaires et retour que la valeur de décalage à l'appelant

::operator delete() va faire la même chose en sens inverse - sh ift le pointeur, accède à des données supplémentaires, libère la mémoire.

Maintenant la question est comment allouer la mémoire? Bien sûr, je peux appeler malloc() ou une fonction spécifique à la plate-forme (c'est comme cela que cela se fait habituellement). Mais normalement, quand j'ai besoin d'allouer de la mémoire brute en C++, j'appelle ::operator new(). Puis-je appeler l'original ::operator new() pour faire l'allocation de mémoire à l'intérieur de mon global surchargé ::operator new()?

+8

Voulez-vous dire surchargé ou remplacé? En cas de surcharge, appelez simplement l'opérateur d'origine new en utilisant le bon jeu d'arguments. Si remplacé, non vous ne pouvez pas mais je crois que c'est _why_ 'malloc' est garanti de ne pas utiliser' operator new' dans son implémentation (ie pas de boucles involontaires quand l'opérateur new est remplacé) donc vous devriez probablement utiliser 'malloc' . –

+2

@CharlesBailey Vous avez écrit votre réponse comme un commentaire! pour la honte! –

Répondre

18

Vous ne pouvez pas y accéder car il n'est pas vraiment surchargé, c'est le remplacement. Lorsque vous définissez votre propre ::operator new, l'ancien disparaît. C'est à peu près ça.

Essentiellement, vous devez appeler malloc à partir d'un ::operator new personnalisé. Non seulement cela, mais aussi suivre les directions 18.4.1.1/4 pour gérer correctement les erreurs:

Comportement par défaut:

- exécute une boucle: Dans la boucle, la fonction première tente d'allouer le stockage demandé. Si la tentative implique un appel à la bibliothèque C standard fonction malloc est non spécifié. Renvoie un pointeur vers le stockage attribué si la tentative aboutit. Renvoie un pointeur vers le stockage attribué. Sinon, si le dernier argument à set_new_handler() était null, throw bad_alloc.

- Sinon, la fonction appelle le nouveau gestionnaire actuel (18.4.2.2). Si la fonction appelée revient, la boucle se répète.

- La boucle se termine lorsqu'une tentative d'allocation le stockage est réussi ou lorsqu'une fonction de new_handler appelée ne retourne pas.

+1

Et n'oubliez pas de remplacer 'operator delete' aussi, avec' free() '. – wilhelmtell

+0

Je crois que Scott Meyers en parle en détail sur ses livres _Effective C++ _. Le point 8 de la deuxième édition et le chapitre 8 de la troisième, semble-t-il. – wilhelmtell

+0

@Potatoswatter: Impossible d'utiliser 'malloc()' pour allouer la mémoire pour sa classe et ses données supplémentaires, puis d'appeler 'placement-new' pour instancier l'objet de classe dans cette mémoire. Comme il ne remplace que la version normale de 'new', le' placement-new' par défaut ne serait-il pas appelé? – Praetorian

Questions connexes