D'accord. Maintenant je cherche à provoquer un plantage. Arme est un pointeur dans Personnage. Le constructeur de copie que j'ai crée dans Personnage copie le pointeur et non pas l'objet pointé. david et goliath possède alors le meme objet arme. Et je me demande pourquoi ca ne plante pas.
Voici mon code :
Personnage.h
class Personnage
{
public:
Personnage();
Personnage(std::string nomArme, int degatsArme);
Personnage(const Personnage &personnageACopier);
void recevoirDegats(int nbDegats);
void attaquer(Personnage &cible);
void boirePotionDeVie(int quantitePotion);
void changerArme(std::string nomNouvelleArme, int degatsNouvelleArme);
bool estVivant();
void afficherEtat();
~Personnage();
private:
int m_vie;
int m_mana;
Arme* m_arme;
//std::string m_nomArme; // Pas de using namespace std, donc il faut mettre std:: devant string.
//int m_degatsArme;
};
Personnage.cpp
//Personnage::Personnage() : m_vie(100), m_mana(100), m_nomArme("Epée rouillée"), m_degatsArme(10) {}
Personnage::Personnage() : m_vie(100), m_mana(100)
{
m_arme = new Arme();
}
//Personnage::Personnage(string nomArme, int degatsArme) : m_vie(100), m_mana(100), m_arme(nomArme, degatsArme) {}
Personnage::Personnage(string nomArme, int degatsArme) : m_vie(100), m_mana(100)
{
m_arme = new Arme(nomArme, degatsArme);
}
Personnage::Personnage(const Personnage &personnageACopier)
{
m_vie = personnageACopier.m_vie;
m_mana = personnageACopier.m_mana;
m_arme = personnageACopier.m_arme;
//m_arme = new Arme(personnageACopier.m_arme);
}
Personnage::~Personnage()
{
delete m_arme;
}
void Personnage::recevoirDegats(int nbDegats)
{
m_vie -= nbDegats;
if (m_vie < 0)
m_vie = 0;
}
void Personnage::attaquer(Personnage &cible)
{
cible.recevoirDegats(m_arme->getDegats());
}
void Personnage::boirePotionDeVie(int quantitePotion)
{
m_vie += quantitePotion;
if (m_vie > 100)
m_vie = 100;
}
void Personnage::changerArme(std::string nomNouvelleArme, int degatsNouvelleArme)
{
m_arme->changer(nomNouvelleArme, degatsNouvelleArme);
}
bool Personnage::estVivant()
{
if (m_vie > 0)
return true;
else
return false;
}
void Personnage::afficherEtat()
{
cout << "Vie : " << m_vie << endl;
cout << "Mana : " << m_mana << endl;
m_arme->afficher();
}
Voici mon main :
int main()
{
// Création des personnages
//Personnage david, goliath("Epée aiguisée", 20);
Personnage goliath("Epée aiguisée", 20);
Personnage david = goliath;
// Au combat !
goliath.attaquer(david);
david.boirePotionDeVie(20);
goliath.attaquer(david);
david.attaquer(goliath);
goliath.changerArme("Double hache tranchante vénéneuse de la mort", 40);
goliath.attaquer(david);
// Temps mort ! Voyons voir la vie de chacun...
cout << "David" << endl;
david.afficherEtat();
cout << endl << "Goliath" << endl;
goliath.afficherEtat();
//goliath.~Personnage();
//david.~Personnage();
return 0;
}
Le resultat :
David
Vie : 40
Mana : 100
Arme : Double hache tranchante vénéneuse de la mort (Dégâts : 40)
Goliath
Vie : 80
Mana : 100
Arme : Double hache tranchante vénéneuse de la mort (Dégâts : 40)
Ensuite, le destructeur s'appelle avec "delete" et non avec "~Personnage "
Pour finir il n'y a besoin d'appeler le destructeur qu'en cas d'objet alloué dynamiquement (de pointeur si tu préfères). Et là tu alloue deux objets normaux qui seront détruits automatiquement.
Dans la même veine, mais un peu différent, les membres dynamiques. La règle est simple : tout new correspond à un delete. Tes membres dynamiques ne sont détruit que si tu le fait explicitement dans le destructeur. C'est pour ça que pour répondre, nous avons besoin de morceau de codes.