Ne supprimez travailler avec des pointeurs de classe de base?
Avez-vous à transmettre supprimer le pointeur de même a été renvoyé par le nouveau, ou vous pouvez passer un pointeur à l'une des classes de types de base? Par exemple:
class Base
{
public:
virtual ~Base();
...
};
class IFoo
{
public:
virtual ~IFoo() {}
virtual void DoSomething() = 0;
};
class Bar : public Base, public IFoo
{
public:
virtual ~Bar();
void DoSomething();
...
};
Bar * pBar = new Bar;
IFoo * pFoo = pBar;
delete pFoo;
Bien sûr, cela est grandement simplifiée. Ce que je veux vraiment faire est de créer un conteneur plein de boost::shared_ptr et de le passer à un code qui supprime le conteneur quand il est fini. Ce code ne saura rien de la mise en œuvre de la Barre ou de la Base, et va s'appuyer sur l'implication d'un opérateur d'effacement dans le shared_ptr destructeur de faire la bonne chose.
Cela peut-il travailler? Mon intuition me dit non, car les pointeurs n'aura pas la même adresse. D'autre part, un dynamic_cast<Bar*> devrait fonctionner, donc quelque part le compilateur est de stocker assez d'informations pour comprendre.
Merci pour l'aide, tout le monde qui a répondu et commenté. Je connaissais déjà l'importance de virtuel destructeurs, comme le montre mon exemple; après avoir vu la réponse que j'ai donné un peu de réflexion, et a réalisé le raison pour un destructeur virtuel est ce scénario exact. Ainsi, il a dû travailler. J'ai été jeté par l'absence de moyens visibles de convertir le pointeur vers l'original. Un peu plus de réflexion m'a amené à croire qu'il y avait un des moyens invisibles, et je pense que le destructeur est le retour de la vraie pointeur pour supprimer la libération. Enquête sur le code compilé à partir de Microsoft VC++ a confirmé mes soupçons quand j'ai vu cette ligne dans ~Base:
mov eax, DWORD PTR _this$[ebp]
Retraçant l'assembleur a révélé que c'était le pointeur passé à la fonction de suppression. Mystère résolu.
J'ai fixé l'exemple pour ajouter le destructeur virtuel à IFoo, c'était une simple surveillance. Merci encore à tous ceux qui l'a signalé.
Vous devez vous connecter pour publier un commentaire.
Oui, il va travailler, si et seulement si la classe de base destructeur est virtuel, qui vous ont fait pour la
Base
de la classe de base, mais pas pour leIFoo
de la classe de base. Si la classe de base destructeur est virtuel, puis quand vous appelezoperator delete
sur la base de pointeur de classe, il utilise la distribution dynamique de comprendre comment faire pour supprimer l'objet en cherchant le destructeur de classe dérivée de la fonction virtuelle table.Dans votre cas de l'héritage multiple, il ne fonctionnera que si la classe de base, vous êtes le supprimer grâce a un destructeur virtuel; c'est ok pour les autres classes de base pour ne pas avoir un destructeur virtuel, mais seulement si vous n'essayez pas de supprimer tout des objets dérivés par les autres de la classe de base des pointeurs.
Ce n'est pas en rapport à votre exemple, mais puisque vous avez mentionné que vous êtes vraiment intéressé à
shared_ptr
le comportement lors de la suppression de son objet appartenant, vous pourriez être intéressés par l'utilisation deshared_ptr
's 'deleter'.Si l'objet possédé par le
shared_ptr
besoins spéciaux de manutention lors de la suppression, vous pouvez spécifier une "deleter" pour un particuliershared_ptr<>
. La deleter ne fait pas partie de la nature, c'est un attribut d'unshared_ptr<>
exemple, si votre conteneur deshared_ptr<>
objets pourraient avoir certains objets avec différentes deleters. Voici ce que le coup de pouce docs disent à propos de l'shared_ptr<>
deleter:Il serait plus propre si vous pouviez modifier
IFoo
avoir un destructeur virtuel puisque vous avez l'intention de supprimer des objets qui sont des sous-classes par uneIFoo
de référence ou un pointeur. Mais si vous êtes coincé avec unIFoo
qui ne peut pas être corrigée, si vous souhaitez utilisershared_ptr<IFoo>
dans votre conteneur, mais il en montrant uneBar
, vous pouvez créer leshared_ptr
exemple avec un deleter, qui effectue une triste pour unBar*
effectue ensuite l'opération de suppression. Downcasts sont considérés comme une mauvaise forme, mais cette technique pourrait être quelque chose que vous pouvez utiliser dans une impasse.