这涉及一些相当棘手的遗产,但在这里忍受我。 我的问题不是一个特定的错误,而只是“我将如何具体地做这个?”
这个想法是有一个抽象的基类食物(注意这个问题都是过于简化的)
//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
};
所以基本上所有东西都来自食物...但这是一件坏事。
我已经尝试了以下几个问题
我在Animal中尝试了虚拟功能的初始版本,并没有任何食物,它抱怨食物没有功能搜索
error C2039: 'hunt' : is not a member of 'Food'
....我认为这是公平的,虽然不应该看松鼠而不是食品类?
我尝试在食物中制作一个纯粹的虚拟食物用于进食和狩猎,从那时起,每次尝试实例化任何类型的叶子类(如松鼠或老虎或其他任何东西)都会返回“无法实例化抽象类”错误。
error C2259: 'Squirrel' : cannot instantiate abstract class
我尝试在食物中进食和狩猎不那么抽象,比如狩猎(list&amp; foodlist),但后来它说“语法错误,标识符'列表'”,就像它不知道列表是什么.. ..即使我加入Food.h后
error C2061: syntax error : identifier 'list'
并且所有这些错误都与错误“'Food :: hunt'配对:函数不带1个参数”
error C2660: 'Food::hunt' : function does not take 1 arguments
我的整体问题是,你如何将这个抽象的虚函数从Animal转换为它的叶子类?你怎么称呼它?基本上我所尝试的一切都是悲惨地失败 * 不要担心里面吃什么()或打猎(),我只是在寻找适当的声明 *
这个项目的github也可以在这里找到 https://github.com/joekitch/OOP_JK_Assignment_4 如果需要的话
答案 0 :(得分:0)
一些想法,
示例代码:
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
};
答案 1 :(得分:0)
我找到的解决方案涉及动态铸造。 基本上,你需要将迭代器指针DOWN从Food *类型转换为更低的类似Herbivore或Animal类型,无论哪种类型必须具有你想要在其中完全定义的函数
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;}
以上代码将尝试将转换为Herbivore 类型。如果它成功(也就是说,它的父类是Herbivore),那么Temp将被转换为左边指定的Herbivore 类型。如果失败,temp将是NULL类型。这个临时指针指向与 it指针相同的东西....但它只是被视为草食动物而不是食物*。