错误 C2259:无法实例化抽象类;或"how exactly should i be using virtual functions here?"

error C2259: cannot instantiate abstract class; or "how exactly should i be using virtual functions here?"

本文关键字:be should using virtual here functions exactly how 实例化 抽象类 错误      更新时间:2023-10-16

这涉及到一些相当棘手的继承,但请耐心听我说。我的问题不是一个具体的错误,而是"我该如何具体地做到这一点?"

的想法是有一个抽象基类Food(注意,这些都是过于简化的问题)

//parent of Animal
//parent of Plant
//~Food()
//Food()
#pragma once
class Food
{
public:
    Food(){}
    ~Food(){}

};

动物和植物就是从那里来的。我现在不太担心植物动物需要有捕猎和进食的虚拟功能

#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

};

这里是main

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中尝试了初始版本的虚拟功能,在food中没有,它抱怨food没有功能hunt

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

…我想这是公平的,尽管它不应该看着松鼠而不是食物班吗?

我尝试在Food for eat and hunt中创建一个纯虚拟,从那时起,每次尝试实例化任何类型的叶子类(如松鼠或老虎或其他)都会返回"无法实例化抽象类"错误。

error C2259: 'Squirrel' : cannot instantiate abstract class

我试着让吃和狩猎在食物不那么抽象,像狩猎(列表&foodlist),但后来它说"语法错误,标识符'列表'",就像它不知道列表是....即使我包含在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

我的总体问题是,你如何将这个抽象的虚函数从Animal转换到它的叶子类?那你怎么称呼它呢?基本上我所尝试的一切都失败了。*不要担心eat()或hunt()里面有什么,我只是在寻找合适的声明*

项目的github也可以在这里获得https://github.com/joekitch/OOP_JK_Assignment_4如果需要

我找到的解决方案涉及动态强制转换。基本上,你需要将迭代器指针从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指针....相同的东西但它只是被当作草食动物而不是食物*。

一些想法,

  • 我假设Herbivore在某处被定义…
  • 使用虚析构函数
  • 当某些东西告诉你它不能在某处实例化时,正在调用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
};

相关文章: