0

これにはかなりトリッキーな継承が含まれますが、ここで我慢してください。私の質問は特定のエラーではなく、単に「これを具体的にどのように行うか」です。

アイデアは、抽象基本クラス Food を持つことです(これはすべて、質問のために単純化しすぎていることに注意してください)

//parent of Animal
//parent of Plant
//~Food()
//Food()
#pragma once

class Food
{
public:
    Food(){}
    ~Food(){}



};

そこから動物や植物のクラスが生まれます。植物については今のところあまり心配していません 動物には仮想機能が必要です Hunt and Eat

#pragma once
#include "Food.h"


class Animal : public Food
{
//eat() which accepts a Food* type as an argument. it is an abstract virtual in this class, it has the form
//bool eat(Food* food)

//hunt() which accepts an stl list of Food* pointers to Food type objects. the food list is declared globally in main and passed here. it has the form
//hunt(list<Food*> &foodlist)
};

そこからさらに多くのクラスが生まれます。草食動物、肉食動物、雑食動物 (肉食動物と草食動物から継承)。これは草食動物です

//Child of Animal
//Parent of Lemur, Koala, Squirrel, Omnivore

//~Herbivore()
//hunt(list<Food*&foodList):bool (only eats plant types)
#pragma once
#include "Animal.h"
#include <iostream>
#include <string>
#include <list>
using namespace std;

class Herbivore : public virtual Animal
    {
    public:

        Herbivore() {}
        ~Herbivore(){}
        //eat() and hunt() are probably virtual here as well, as they aren't used directly, only the lower classes directly access them


};

そしてそれらから最下位の子クラスがあり、それらはすべておおよそこの形式を持っています。これはリスです

//child of Herbivore
//leaf node

#pragma once
#include "Animal.h"
#include "Herbivore.h"

class Squirrel : public Herbivore
{ 

        //bool eat() is fully defined here instead of being virtual.
        //bool hunt() is fully defined here instead of being a virtual.

       //both have the same argument lists as the virtuals in Animal



};

そしてメインはこちら

list<Food*> Food_list; //global list of Food items that will be passed to hunt()
int main()
{

    list<Food*>::iterator it = Food_list.begin();

    (*it)->eat(*it); //passing the iterator to itself as a test. this seems to work ok
    (*it)->hunt(Food_list); //however this, in my code, refuses to work for a few reasons

};

基本的にすべて食べ物から受け継いでいますが、これは悪いことです。

私は次の問題でいくつかのことを試しました

アニマルで仮想関数の初期バージョンを試してみましたが、フードには何もありませんでした。フードには関数ハントがないと不平を言いました

error C2039: 'hunt' : is not a member of 'Food' 

....これは公平だと思いますが、食品クラスではなく、リスを見るべきではありませんか?

私は食べ物と狩りのために純粋な仮想を作成しようとしましたが、その時点から、あらゆる種類のリーフ クラス (リスやトラなど) をインスタンス化しようとすると、「抽象クラスをインスタンス化できません」というエラーが返されました。

error C2259: 'Squirrel' : cannot instantiate abstract class

ハント(リスト&フードリスト)のように、食べ物の食べて狩りを抽象度を下げようとしましたが、「構文エラー、識別子「リスト」」と表示され、リストが何であるかがわからないようです.... Food.h に含める

error C2061: syntax error : identifier 'list'

これらのエラーはすべて、「'Food::hunt': function does not take 1 arguments」というエラーと対になっています。

error C2660: 'Food::hunt' : function does not take 1 arguments

私の全体的な質問は、この抽象仮想関数をアニマルからそのリーフクラスにどのように転置しますか? そして、あなたはそれをどのように正確に呼びますか? 基本的に私が試したことはすべて惨めに失敗しました * eat() や hunt() の中身は気にしないでください。適切な宣言を探しているだけです*

プロジェクトのこの github は、 必要に応じてhttps://github.com/joekitch/OOP_JK_Assignment_4からも入手できます。

4

2 に答える 2

0

私が見つけた解決策には、動的キャストが含まれます。基本的に、イテレータ ポインターを Food* 型から草食動物型や動物型などの下位の型にキャストする必要があります。どちらの方法でも、その型には完全に定義したい関数が含まれている必要があります。

Herbivore* temp = dynamic_cast<Herbivore*>(*it)
if ( temp ){
        cout << "iterator thing is a Herbivore " << endl;
        temp->hunt(Food_list);
    cout << "iterator thing is of the type " << typeid(temp).name() << endl;}
    else cout << "iterator is not a Herbivore " << endl;}

上記のコードは、それを草食動物型にキャストしようとします。成功した場合 (つまり、親クラスが草食動物である場合)、Temp は左側で指定された草食動物タイプにキャストされます。失敗した場合、temp は NULL 型になります。この temp ポインターは it ポインターと同じものを指しています....しかし、それは単純に Food* ではなく草食動物として扱われます。

于 2013-05-09T13:38:51.340 に答える
0

いくつかの考え、

  • 草食動物はどこかで定義されていると思います...
  • 仮想デストラクタを使用する
  • Food()、Animal() コンストラクターが呼び出されています。

コード例:

class Food
{
public:
    Food(){ }
    virtual ~Food(){ }
};

class Animal : public Food
{
 Animal() : Food() { }
 virtual Animal() { } //Cause C++

 virtual bool eat(Food* food) = 0;
 virtual hunt(list<Food*> &foodlist) = 0;
};

class Squirrel : public Herbivore
{ 
 Squirrel() : Herbivore() { }
 ~Squirrel() { } //not virtual

  bool eat(Food *food) { //stuff };
  void hunt(list<Food *> &foodlist) { //stuff };
};

list<Animal*> animal_list; //global list of Food items that will be passed to hunt()
int main()
{
    animal_list.push_back(new Squirrel()); // Make sure you fill the array?

    list<Food*>::iterator it = Food_list.begin();

    (*it)->eat(*it); //passing the iterator to itself as a test. this seems to work ok
    (*it)->hunt(animal_list); //however this, in my code, refuses to work for a few reasons

};
于 2013-05-09T02:56:45.777 に答える