2013-05-10 79 views
0

問題的結構是這樣的 食物是一個抽象基類;植物和動物直接從它那裏繼承。 食草動物,食肉動物和雜食動物繼承動物, 而水果和堅果和葉從植物 繼承狐猴,考拉和松鼠繼承草食動物dynamic_cast只能正確執行

總體而言,它是一個炎熱的爛攤子,但它是必要的鍛鍊。 整個項目可以在GitHub https://github.com/joekitch/OOP_JK_Assignment_4/blob/master/OOP_JK_Assignment_4/Lemur.h 完整的類圖中也對GitHub的

,但這裏有相關的位和鮑勃(至少,那些我認爲是相關的) 首先是食品類,它包含了幾乎沒有什麼

#pragma once 
#include <string> 
#include <list> 
using namespace std; 

class Food 
{ 
public: 

    Food(){ } 
    virtual ~Food(){ } 


}; 

下一個是動物,它包含了追捕(的虛函數),吃()函數

#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; 
}; 

這是Herbivore,它完全定義了hunt()函數,這是問題開始的地方(請參閱我在hunt()中的註釋)。狩獵需要在全球範圍內主要宣佈的類型Food *的列表()

#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; 
      for (list<Food*>::iterator it = foodlist.begin(); it != foodlist.end(); it++) 
      { 
       if (Plant* temp = dynamic_cast<Plant*>(*it)) 
       { 
//this is there the problems start. the above dynamic cast SHOULD make temp 
//non-null if the thing i'm looking at is a child of plant (that is, if the thing 
//in the food list is a fruit or a nut or a leaf). And indeed it does...but the 
//next dynamic cast (in the eat() function of Lemur) doesn't detect any fruits.... 

        plantcounter++; 

        if (eat(*it)) 
        fruitcounter++; 
        //return true; 
       } 

      } 
      cout << "there are " << fruitcounter << " fruits and " << plantcounter << " plants in the list." << endl; 
      return false; 
     }; 


}; 

這裏是Fruit類。沒有什麼特別明顯的,我只是把它放在這裏只是在情況下,他們可以幫助解決這個問題

#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 to base class 

     ~Fruit(){ } //destructor 

     //inherits basically everything from the Plant base class, makes leae nodes in the class tree easy to write and access 



    }; 

現在這裏是真正的麻煩製造者。這個狐猴完全定義了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, it sees every plant as a fruit in this 
//case...at least according to a typeinfo().name() that i have run in here. However the temp 
//always returns null, so this proper if statement never actually happens, so it never sees 
//any fruit, even though there's a whole bunch in the list (500 of them). what's wrong? 
       cout << "it's a fruit" << endl; 
       return true; 
      } 
      else 
      { 
       //cout << "not a fruit" << endl; 
       return false; 
      } 


     } 


    void PrintSelf() 
    { 
     cout << "i am a " << age << " year old, " << weight << " kilogram " << name << " with " << calories << " calories." << endl; 
    }; 

    string& getName(){ 
     return name; 
    }; 

     std::string name; 
     bool alive; 
     int age, calories, maxcalories; 
     double weight; 


}; 

,你可以看到,將dynamic_cast不會返回一個非空氣溫,即使我已經證實,它遍歷該列表。我也使用計數器變量來追蹤它的進度,奇怪的是它說有1500個植物在列表中......但是0個水果......

我在構造我的演員是錯的嗎?我的遺傳是關閉的嗎?做什麼?

編輯;我添加的虛擬析構函數爲每個類,所以這是不看的github回購問題

回答

0

,看起來問題出在哪裏main.cpp你對象添加到Food_list

else if (FileIn_type == Plant_type) 
{ 
    Plants++; 
    FileIn >> FileIn_name >> FileIn_calories; 
    Food_list.push_back(new Plant (FileIn_name, FileIn_calories)); 
} 

您只能創建一個要添加到列表中的Plant對象。所以這就是所有這些對象的動態類型。

僅僅在main.cpp的代碼位之上,您可以創建級聯的if/else語句,這些語句在動物名稱字符串中創建不同的動物類型。你需要爲植物做類似的事情。

+0

啊哈!那一定是它。這也是有意義的,植物下面什麼也沒有,所以演員總是會失敗,因爲首先在植物下面沒有任何東西 – user2364502 2013-05-10 10:58:22