Appel de fonction virtuelle pure
Bonjour,
J'ai deux classes, dont l'une gère l'autre (code source ci-après). Il se trouve que lors de la destruction de la première classe, j'ai un appel à une fonction virtuelle pure. Je tiens à préciser que j'ai cherché sur internet un solution éventuelle à mon problème, mais je n'ai rien trouvé qui corresponde vraiment à mon problème.
Donc voici le code:
action_manager.h:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #ifndef _ACTIONS_LIST_INCLUDED_
#define _ACTIONS_LIST_INCLUDED_
#include <list>
#include "systemLists.h"
#include "..\devicesStruct.h"
class Entity;
class Action;
class ActionsList
{
public:
//! Constructeur et destructeur
ActionsList(SDevices* devs, Entity* owner);
~ActionsList();
//! Gestion des actions
void addAction(ENUM_ACTION_INDEXES_LIST action);
void popAction();
void clear();
//! Mise à jour
void execute(float deltaT);
//! Informations
int getActionCount();
SDevices* getDevices();
private:
void activateFirstAction();
std::list<Action*> actList;
Entity* actionsOwner;
int totalActions;
SDevices* devices;
};
#endif // _ACTIONS_LIST_INCLUDED_ |
action_manager.cpp:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include "ActionsBase.h"
#include "ActionsList.h"
#include "..\Entity\Entity.h"
//! Actions de base
void Action::setEntityAnimation(unsigned int start, unsigned int end)
{
float num = object->getSceneNode()->getFrameNr();
object->setAnimationRange(start,end);
if(num>=start && num<=end) object->getSceneNode()->setCurrentFrame(num);
}
//! Constructeur et destructeur
ActionsList::ActionsList(SDevices* devs, Entity* owner)
:actionsOwner(owner),totalActions(0),devices(devs)
{
}
ActionsList::~ActionsList()
{
printf("Clearing...\n");
clear();
printf("Cleared !\n");
}
//! Gestion des actions
void ActionsList::addAction(ENUM_ACTION_INDEXES_LIST action)
{
if(baseActions[(int)action])
{
Action* act = baseActions[(int)action]->cloneType();
act->manager = this;
act->object = actionsOwner;
actList.push_back(act);
totalActions++;
act->OnActionCreation();
if(totalActions==1)
activateFirstAction();
}
}
void ActionsList::popAction()
{
if(actList.begin() != actList.end())
{
Action* act = *actList.begin();
act->OnActionDeletion();
delete act;
actList.erase(actList.begin());
totalActions--;
activateFirstAction();
}
}
void ActionsList::clear()
{
while(actList.begin() != actList.end())
popAction();
}
//! Mise à jour
void ActionsList::execute(float deltaT)
{
if(actList.begin() != actList.end())
(*(actList.begin()))->exec(deltaT);
else addAction(EAIL_IDLE);
}
//! Informations
int ActionsList::getActionCount()
{
return totalActions;
}
SDevices* ActionsList::getDevices()
{
return devices;
}
//! Privé
void ActionsList::activateFirstAction()
{
if(actList.begin() != actList.end())
{
Action* act = *actList.begin();
// Voici la fonction qui plante :
act->OnActionActivation();
}
} |
L'appel à la fonction OnActionActivation plante uniquement lorsque l'actionlist est détruite. J'ai fait le test, en cours d'exécution + de 5000 appels de cette fonction ne font absolument aucune erreur...
Par contre, quand on l'appelle depuis le destructeur d'ActionList (via clear() -> popAction() ), ca plante dès la première exécution...
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
#include "..\devicesStruct.h"
#include "systemLists.h"
#include "ActionsList.h"
#include "..\type.h"
#include <vector>
class Entity;
struct Action
{
//! La classe dont dépendent les actions
ActionsList* manager;
Entity* object;
//! Les données de l'action
std::vector<VoidValue> data;
//! Destructeur virtuel
virtual ~Action() {}
//! Slots
virtual void OnActionCreation() =0;
virtual void OnActionActivation() =0;
virtual void OnActionDeletion() =0;
//! Fonctions principales
virtual void exec(float deltaT) =0;
virtual Action* cloneType() =0;
virtual void escapeIfOtherActionsInList()
{ if(manager->getActionCount()>1) manager->popAction(); }
virtual void finish()
{ manager->popAction(); }
virtual void setEntityAnimation(unsigned int start, unsigned int end);
//! RTTI
virtual ENUM_ACTION_INDEXES_LIST getType() =0;
}; |
Toutes les fonctions sont bien réimplémentées dans les classes filles...
Et j'obtient l'erreur meme si je met
Code:
virtual void OnActionActivation() {printf("Act!\n");}
au lieu de
Code:
virtual void OnActionActivation() =0;
dans la classe de base...
Quelqu'un aurait il une idée ?
Merci d'avance.