Il s'agit d'une question de conception, en supposant C++ et une hiérarchie d'objets comptés de référence. Un grand nombre de classes dans mon code dérivent d'une classe de base commune (ObjectBase), qui implémente des méthodes retain() et release() pour augmenter et diminuer le nombre de références d'une instance d'objet.Objets comptés de référence et multiplicateurs
Chaque instance d'un objet peut être créée sur la pile ou sur le tas, en utilisant un certain nombre d'allocateurs de mémoire définissables par l'utilisateur. Pour que l'instance d'objet se suicide (supprimez ceci) dans la méthode release() si la propriété retainCount atteint 0, l'instance doit connaître l'allocateur avec lequel elle a été construite.
Actuellement, j'alloue de la mémoire pour une instance d'objet en utilisant un allocateur arbitraire, puis appelle placement new pour construire l'instance d'objet et appelle une méthode setAllocator() sur l'objet pour définir l'allocateur avec lequel elle a été créée. Si l'objet a été construit sur la pile, l'allocateur est défini sur NULL et release() n'appelle pas delete. Ce processus est très redondant et potentiellement sujette aux erreurs (fuites de mémoire, si j'oublie d'appeler setAllocator, etc ...) Idéalement, je voudrais faire une seule étape comme ceci:
Object* o = myPoolAllocator.allocate<Object>(constructor arguments...);
Mais cela fait il est très difficile de soutenir et le nombre arbitraire d'arguments constructeur.
Je cherche juste des idées sur la façon de résoudre ce problème. J'aime vraiment l'idée de pouvoir référencer des objets sans avoir à compter sur un pointeur intelligent, d'autant plus que la plupart des classes dérivent d'une base commune, de toute façon.
Merci pour votre aide.
Florian
casablanca, merci pour votre réponse rapide et merci pour la fixation de la balise source dans mon OT! J'ai considéré une méthode similaire à celle que vous suggérez, mais comme vous l'avez noté correctement, je ne serai plus capable de créer des objets sur la pile. J'ai pensé à vérifier dans le constructeur ObjectBase, si le champ d'allocateur pointe vers une instance d'allocateur valide et si ce n'est pas le cas, en considérant l'objet à être sur la pile. Cependant, il s'agit d'une activité dangereuse, étant donné qu'il existe certaines (bien que petites) chances que le champ allocateur non initialisé pointe vers un allocateur valide. – FlorianZ
@FlorianZ: Voir ma réponse mise à jour pour encore un autre hack possible. – casablanca
@casablanca. C'est une très bonne idée aussi! Ma seule préoccupation à ce sujet est que ce n'est probablement pas thread-safe. Que se passe-t-il si un changement de contexte se produit après le retour de l'opérateur, mais avant que le constructeur n'ait une chance de consommer la variable currentAllocator. Si les allocations sont ensuite exécutées dans le deuxième thread, currentAllocator serait alors compromis. Des idées sur la façon de rendre votre solution sûre pour les threads? – FlorianZ