c++ - dynamic_cast performing correctly only sometimes -


the structure of problem such food abstract base class; plant, , animal directly inherit that. herbivore, carnivore, , omnivore inherit animal, while fruits , nuts , leaves inherit plant lemur, koala, , squirrel inherit herbivore

overall it's hot mess, it's necessary exercise. entire project available on github https://github.com/joekitch/oop_jk_assignment_4/blob/master/oop_jk_assignment_4/lemur.h the full class diagram in on github

but here relevant bits , bobs (at least, ones believe relevant) first food class, contains nothing

#pragma once #include <string> #include <list> using namespace std;  class food { public:      food(){ }     virtual ~food(){ }   }; 

next animal, contains virtuals of hunt() , eat() functions

#pragma once #include "food.h" #include "animal.h" #include "plant.h" #include <iostream> #include <string> #include <list> using namespace std;  class animal : public food { public:     animal(void) : name(), alive(true), age(0), calories(0), weight(0) { }         animal(string& animal_name, int animal_age, int animal_calories, double animal_weight) :          name(animal_name), alive(true), age(animal_age), calories(animal_calories), weight(animal_weight), maxcalories(animal_calories) {}      virtual ~animal(){}      virtual bool eat(food* food){return false;};     virtual bool hunt(list<food*> &foodlist){return false;};       virtual void printself(){};      virtual string& getname(){         return name;     };           std::string name;         bool alive;         int age, calories, maxcalories;         double weight; }; 

this herbivore, defines hunt() function, problems start (see comment within hunt() ). hunt takes in list of type food* declared globally within main()

#pragma once #include "animal.h" //#include "lemur.h" #include "plant.h" #include "fruit.h" #include "leaf.h" #include "nut.h" #include <iostream> #include <string> #include <list> #include <typeinfo> using namespace std;  class herbivore : public virtual animal     {     public:         herbivore() {}         virtual ~herbivore(){}         virtual bool eat(food* food) {cout << "herbivore.h eat() called" << endl; return true;};            bool hunt(list<food*> &foodlist) //herbivore version of hunt()         {             int fruitcounter=0;             int plantcounter=0;             string name;             (list<food*>::iterator = foodlist.begin(); != foodlist.end(); it++)             {                 if (plant* temp = dynamic_cast<plant*>(*it))                 { //this there problems start. above dynamic cast should make temp  //non-null if thing i'm looking @ child of plant (that is, if thing  //in food list fruit or nut or leaf). , indeed does...but  //next dynamic cast (in eat() function of lemur) doesn't detect fruits....                      plantcounter++;                      if ( eat(*it) )                     fruitcounter++;                     //return true;                 }              }             cout << "there " << fruitcounter << " fruits , " << plantcounter << " plants in list." << endl;             return false;         };   }; 

and here fruit class. nothing particularly notable, i'm placing here in case helps solve problem

#pragma once #include <iostream> #include <string> #include "plant.h" using namespace std;  class fruit : public plant {     public:         fruit (std::string& plant_name, int energy_value):           plant (plant_name, energy_value){} //constructor pased base class          ~fruit(){ } //destructor          //inherits plant base class, makes leae nodes in class tree easy write , access        }; 

now here's real troublemaker. lemur defines eat() function, , takes food* passed hunt(), called herbivore, , more tests on see if it's fruit (which plant lemur can eat)

#pragma once #include "animal.h" #include "herbivore.h" #include "plant.h" #include "fruit.h" #include "leaf.h" #include "nut.h" #include <iostream> #include <string> #include <list> #include <typeinfo> using namespace std;  class lemur : public herbivore {     public:         lemur(void) : name(), alive(true), age(0), calories(0), weight(0) {}         lemur(string& animal_name, int animal_age, int animal_calories, double animal_weight) :          name(animal_name), alive(true), age(animal_age), calories(animal_calories), weight(animal_weight), maxcalories(animal_calories) {}           ~lemur(){}            bool eat(food* food)         {                 if (fruit* temp = dynamic_cast<fruit*>(food))             {                 //problem, sees every plant fruit in //case...at least according typeinfo().name() have run in here. temp //always returns null, proper if statement never happens, never sees //any fruit, though there's whole bunch in list (500 of them). what's wrong?                 cout << "it's fruit" << endl;                 return true;             }             else             {                 //cout << "not fruit" << endl;                 return false;             }           }       void printself()     {         cout << "i " << age << " year old, " << weight << " kilogram " << name << " " << calories << " calories." << endl;     };      string& getname(){         return name;     };          std::string name;         bool alive;         int age, calories, maxcalories;         double weight;   }; 

as can see, dynamic_cast never returns non null temp, though have confirmed traverses list. use counter variables track progress , strange thing says there 1500 plants in list...but 0 fruits...

am structuring casts wrong? inheritance off? do?

edit; added virtual destructors every class, isn't problem

from looking @ github repo, looks problem in main.cpp add object food_list:

else if (filein_type == plant_type) {     plants++;     filein >> filein_name >> filein_calories;     food_list.push_back(new plant (filein_name, filein_calories) ); } 

you ever create plant object add list. that's dynamic type of objects be.

just above bit of code in main.cpp, have cascade of if/else statements create different animal types baed on animal name string. need similar plants.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

qt - Errors in generated MOC files for QT5 from cmake -