0

When I launch my game, it seems to crash when I call the constructor. All it says is "a.exe has stopped working" and then I have to close the program. I've tried tracing the problem back through all my linked classes and headers but I can't see anything wrong. Maybe one of you can help me. Here are the involved classes:

#ifndef POKEMON_H_
#define POKEMON_H_

#include "MoveList.cpp"
#include "Elements.cpp"

    class Pokemon
    {
    protected:
        std::string name;
        double HP;
        vector<Move> potentialMoves;
        vector<Move> moves;
        int attack;
        int defense;
        int speed;
        int special;
        Elements element;
        std::string type; 
        char status; // (N)ormal, (B)urnt, (F)rozen, E - Paralyzed, (P)oisoned, (S)leep, (C)onfused
        // int ability;
        int ID;
        int level;
        double experience;
        bool isInAir;
        bool isInGround;
    public:
        Pokemon(double HP, int attack, int defense, int speed, int special, int elementNumber, std::string type, int ID, std::string name);
        ~Pokemon();
        virtual void setName(string x);
        virtual string getName();
        virtual void setHP(double x);
        virtual double getHP();
        virtual void setPotentialMoves(vector<Move> x);
        virtual vector<Move> getPotentialMoves();
        virtual Move& getPotentialMove(int x);
        virtual void setAttack(int x);
        virtual int getAttack();
        virtual void setDefense(int x);
        virtual int getDefense();
        virtual void setSpeed(int x);
        virtual int getSpeed();
        virtual void setSpecial(int x);
        virtual int getSpecial();
        virtual Elements& getElement();
        virtual string getType();
        virtual void setStatus(char x);
        virtual char getStatus();
        virtual int getID();
        virtual void setLevel(int x);
        virtual int getLevel();
        virtual void setExperience(double x);
        virtual double getExperience();
        virtual void setAir(bool x);
        virtual bool getAir();
        virtual void setGround(bool x);
        virtual bool getGround();
        virtual void setMove(const Move& move, int x);
        virtual Move& getMove(int x);
        virtual void attackMove(int moveNumber, Pokemon& opponent);
    };

        class Bulbasaur: public Pokemon
        {
        public:
            Bulbasaur(double HP, int attack, int defense, int speed, int special, string name);
            ~Bulbasaur();
        };

        class Ivysaur: public Pokemon
        {
        public:
            Ivysaur(double HP, int attack, int defense, int speed, int special, string name);
            ~Ivysaur();
        };

        class Venosaur: public Pokemon
        {
        public:
            Venosaur(double HP, int attack, int defense, int speed, int special, string name);
            ~Venosaur();
        };

        #endif

#include "Pokemon.h"
#include <cstdlib>

using namespace std;

Pokemon::Pokemon(double HP, int attack, int defense, int speed, int special, int elementNumber, string type, int ID, string name): HP(HP), attack(attack),
                defense(defense), speed(speed), special(special), type(type), ID(ID), name(name), element(element)
                {
                    ElementsList tempList = ElementsList();
                    moves.push_back(Move());
                    moves.push_back(Move());
                    moves.push_back(Move());
                    moves.push_back(Move());
                    status = 'N';
                    level = 1;
                    experience = 0.0;
                    isInAir = false;
                    isInGround = false;
                    element = tempList.getElement(elementNumber);
                    tempList.~ElementsList();
                }

Pokemon::~Pokemon() {}

void Pokemon::setName(string x)
{
    this->name = x;
}

string Pokemon::getName()
{
    return this->name;
}

void Pokemon::setHP(double x)
{
    this->HP = x;
}

double Pokemon::getHP()
{
    return this->HP;
}

void Pokemon::setPotentialMoves(vector<Move> x)
{
    for(int i = 0; i < x.size(); i++)
    {
        potentialMoves.push_back(x[i]);
    }
}

vector<Move> Pokemon::getPotentialMoves()
{
    return this->potentialMoves;
}

Move& Pokemon::getPotentialMove(int x)
{
    return this->potentialMoves[x];
}

void Pokemon::setAttack(int x)
{
    this->attack = x;
}

int Pokemon::getAttack()
{
    return this->attack;
}

void Pokemon::setDefense(int x)
{
    this->defense = x;
}

int Pokemon::getDefense()
{
    return this->defense;
}

void Pokemon::setSpeed(int x)
{
    this->speed = x;
}

int Pokemon::getSpeed()
{
    return this->speed;
}

void Pokemon::setSpecial(int x)
{
    this->special = x;
}

int Pokemon::getSpecial()
{
    return this->special;
}

Elements& Pokemon::getElement()
{
    return this->element;
}

string Pokemon::getType()
{
    return this->type;
}

void Pokemon::setStatus(char x)
{
    this->status = x;
}

char Pokemon::getStatus()
{
    return this->status;
}

int Pokemon::getID()
{
    return this->ID;
}

void Pokemon::setLevel(int x)
{
    this->level = x;
}

int Pokemon::getLevel()
{
    return this->level;
}

void Pokemon::setExperience(double x)
{
    this->experience = x;
}

double Pokemon::getExperience()
{
    return this->experience;
}

void Pokemon::setAir(bool x)
{
    this->isInAir = x;
}

bool Pokemon::getAir()
{
    return this->isInAir;
}

void Pokemon::setGround(bool x)
{
    this->isInGround = x;
}

bool Pokemon::getGround()
{
    return this->isInGround;
}

void Pokemon::setMove(const Move& move, int x)
{
    this->moves[x] = move;
}

Move& Pokemon::getMove(int x)
{
    return this->moves[x];
}

void Pokemon::attackMove(int moveNumber, Pokemon& opponent)
{
    Move currentMove = this->getMove(moveNumber);
    double damageDealt = opponent.getHP() - currentMove.getHPdiff();
    int attackDifference = opponent.getAttack() - currentMove.getattackDiff();
    int defenseDifference = opponent.getDefense() - currentMove.getdefenseDiff();
    int speedDifference = opponent.getSpeed() - currentMove.getspeedDiff();
    int specialDifference = opponent.getSpecial() - currentMove.getspecialDiff();
    char statusDifference = currentMove.getstatusDiff();
    bool isInAirDifference = currentMove.getisInAirDiff();
    bool isInGroundDifference = currentMove.getisInGroundDiff();
    opponent.setHP(damageDealt);
    opponent.setAttack(attackDifference);
    opponent.setDefense(defenseDifference);
    opponent.setSpeed(speedDifference);
    opponent.setSpecial(specialDifference);
    opponent.setStatus(statusDifference);
    this->setAir(isInAirDifference);
    this->setGround(isInGroundDifference);
}

Bulbasaur::Bulbasaur(double HP, int attack, int defense, int speed, int special, string name):
            Pokemon(HP, attack, defense, speed, special, 4, "Seed", 1, name)
            {
                BulbasaurMoveList temp = BulbasaurMoveList();
                this->setPotentialMoves(temp.getPotentialMoves());
                temp.~BulbasaurMoveList();
                vector<Move> temp2;
                for(int i = 0; i < this->getPotentialMoves().size(); i++)
                {
                    temp2.push_back(this->getPotentialMove(i));
                }
                vector<int> usedNums;
                srand(0);
                int i = 0;
                while(i < 4)
                {
                    int r = rand() % 4;
                    if(i == 0)
                    {
                        usedNums.push_back(r);
                    } else
                    {
                        for(int j = 0; j < usedNums.size(); j++)
                        {
                            if(usedNums[j] == r)
                            {
                                continue;
                            }
                        }
                        usedNums.push_back(r);
                    } 
                    this->setMove(temp2[r], i);
                    i++;
                }
            }

And here is MoveList.cpp:

#include "MoveList.h"
#include <iostream>
#include <vector>

using namespace std;

Move::Move(string name, string type, int PP, double HPdiff, int attackDiff, int defenseDiff, int speedDiff, int specialDiff,
        char statusDiff, bool isInAirDiff, bool isInGroundDiff): name(name), type(type), PP(PP), HPdiff(HPdiff), attackDiff(attackDiff),
    defenseDiff(defenseDiff), speedDiff(speedDiff), specialDiff(specialDiff), statusDiff(statusDiff), isInAirDiff(isInAirDiff),
    isInGroundDiff(isInGroundDiff) {}

Move::Move(): name(), type(), PP(), HPdiff(), attackDiff(), defenseDiff(), speedDiff(), specialDiff(), statusDiff(), isInAirDiff(),
            isInGroundDiff() {}

string Move::getName()
{
    return this->name;
}

string Move::getType()
{
    return this->type;
}

int Move::getPP()
{
    return this->PP;
}

double Move::getHPdiff()
{
    return this->HPdiff;
}

int Move::getattackDiff()
{
    return this->attackDiff;
}

int Move::getdefenseDiff()
{
    return this->defenseDiff;
}

int Move::getspeedDiff()
{
    return this->speedDiff;
}

int Move::getspecialDiff()
{
    return this->specialDiff;
}

char Move::getstatusDiff()
{
    return this->statusDiff;
}

bool Move::getisInAirDiff()
{
    return this->isInAirDiff;
}

bool Move::getisInGroundDiff()
{
    return this->isInGroundDiff;
}

MoveList::MoveList()
{
    masterList.push_back(Move("Pound", "NORMAL", 35, 8.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Karate Chop", "FIGHTING", 25, 10.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Double Slap", "NORMAL", 15, 3.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Comet Punch", "NORMAL", 15, 3.6, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Mega Punch", "NORMAL", 20, 16.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Pay Day", "NORMAL", 20, 8.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Fire Punch", "FIRE", 15, 15.0, 0, 0, 0, 0, 'B', false, false));
    masterList.push_back(Move("Ice Punch", "ICE", 15, 15.0, 0, 0, 0, 0, 'F', false, false));
    masterList.push_back(Move("Thunder Punch", "ELECTRIC", 15, 15.0, 0, 0, 0, 0, 'E', false, false));
    masterList.push_back(Move("Scratch", "NORMAL", 35, 8.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Vice Grip", "NORMAL", 30, 11.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Guillotine", "NORMAL", 5, 100.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Razor Wind", "NORMAL", 10, 20.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Swords Dance", "NORMAL", 20, 0.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Cut", "NORMAL", 30, 10.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Gust", "FLYING", 35, 8.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Wing Attack", "FLYING", 35, 12.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Whirlwind", "NORMAL", 20, 0.0, 0, 0, 0, 0, 'N', false, false));
    masterList.push_back(Move("Fly", "NORMAL", 15, 18.0, 0, 0, 0, 0, 'N', true, false));
    masterList.push_back(Move("Bind", "NORMAL", 20, 3.0, 0, 0, 0, 0, 'N', false, false));
}

MoveList::~MoveList() {}

vector<Move> MoveList::getList()
{
    return this->masterList;
}

BulbasaurMoveList::BulbasaurMoveList()
{
    MoveList y = MoveList();
    vector<Move> z = y.getList();
    potentialMoves.push_back(z[0]);
    potentialMoves.push_back(z[9]);
    potentialMoves.push_back(z[10]);
    potentialMoves.push_back(z[14]);
    y.~MoveList();
}

BulbasaurMoveList::~BulbasaurMoveList() {}

vector<Move> BulbasaurMoveList::getPotentialMoves()
{
    return potentialMoves;
}

IvysaurMoveList::IvysaurMoveList()
{
    MoveList y = MoveList();
    vector<Move> z = y.getList();
    potentialMoves.push_back(z[0]);
    potentialMoves.push_back(z[9]);
    potentialMoves.push_back(z[10]);
    potentialMoves.push_back(z[14]);
    y.~MoveList();
}

IvysaurMoveList::~IvysaurMoveList() {}

vector<Move> IvysaurMoveList::getPotentialMoves()
{
    return potentialMoves;
}

VenosaurMoveList::VenosaurMoveList()
{
    MoveList y = MoveList();
    vector<Move> z = y.getList();
    potentialMoves.push_back(z[0]);
    potentialMoves.push_back(z[9]);
    potentialMoves.push_back(z[10]);
    potentialMoves.push_back(z[14]);
    y.~MoveList();
}

VenosaurMoveList::~VenosaurMoveList() {}

vector<Move> VenosaurMoveList::getPotentialMoves()
{
    return potentialMoves;
}

Elements.cpp:

#include "Elements.h"
#include <string>
#include <vector>
#include <iostream>

using namespace std;

Elements::Elements(string name): name(name) {}

Elements::Elements() {}

ElementsList::ElementsList()
{
    masterList.push_back(Elements("NORMAL"));
    masterList.push_back(Elements("FIRE"));
    masterList.push_back(Elements("WATER"));
    masterList.push_back(Elements("ELECTRIC"));
    masterList.push_back(Elements("GRASS"));
    masterList.push_back(Elements("ICE"));
    masterList.push_back(Elements("FIGHTING"));
    masterList.push_back(Elements("POISON"));
    masterList.push_back(Elements("GROUND"));
    masterList.push_back(Elements("FLYING"));
    masterList.push_back(Elements("PSYCHIC"));
    masterList.push_back(Elements("BUG"));
    masterList.push_back(Elements("ROCK"));
    masterList.push_back(Elements("GHOST"));
    masterList.push_back(Elements("DRAGON"));
}

ElementsList::~ElementsList() {}

Elements ElementsList::getElement(int x)
{
    return masterList[x];
}

And then the main function:

#include "Pokemon.cpp"
#include <iostream>
#include <limits>
#include <cstdlib>

using namespace std;

int main()
{
    cout << "Battle Test 1: Bulbasaur vs. Ivysaur Same Level" << endl;
    cout << "test" << endl;
    try
    {
        Bulbasaur test1 = Bulbasaur(300.0, 20, 30, 10, 5, "Chris");
    } catch(exception& e)
    {
        cout << e.what() << endl;
    }
}
Russell
  • 35
  • 5
  • Why are you calling all those destructors manually? – Jonathan Potter Jul 19 '15 at 20:37
  • 1
    Please create a [Minimal, Complete, Verifiable Example](http://stackoverflow.com/help/mcve) for answerers to understand the problem. (Though in this case I would say that the best thing to do is simply place a breakpoint at the first line of the offending constructor and see what line is crashing. That should provide you enough direction to know how to fix the problem.) – Jonathan Mee Jul 19 '15 at 21:31
  • I'm sorry, what is a breakpoint? I'm a newbie.. – Russell Jul 20 '15 at 04:21

1 Answers1

0

Because you are calling the destructor manually on objects. It is very rare to need to do this (see calling destructor explicitly). When you call your destructor manually, it still gets called again when the object falls out of scope. Take for example:

BulbasaurMoveList::BulbasaurMoveList()
{
    MoveList y = MoveList();
    vector<Move> z = y.getList();
    potentialMoves.push_back(z[0]);
    potentialMoves.push_back(z[9]);
    potentialMoves.push_back(z[10]);
    potentialMoves.push_back(z[14]);
    y.~MoveList();
}

y gets destroyed twice, and this results in undefined behaviour:

Invoking the destructor on an object whose lifetime has ended results in undefined behavior per C++03 §12.4/6:

the behavior is undefined if the destructor is invoked for an object whose lifetime has ended

Community
  • 1
  • 1
Tas
  • 7,023
  • 3
  • 36
  • 51
  • You are awesome, thanks man. Learned something new today. This kind of stuff I would never know because its not in my book im using. – Russell Jul 20 '15 at 04:33