错误 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?"
这涉及到一些相当棘手的继承,但请耐心听我说。我的问题不是一个具体的错误,而是"我该如何具体地做到这一点?"
的想法是有一个抽象基类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
};
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 这对"With a stackless coroutine, only the top-level routine may be suspended."意味着什么
- 为什么我会" void value not ignored as it ought to be"?
- 如何解决"no Qt platform plugin could be initialized"问题?
- C++/SDL "initial value of reference to a non-const must be an lvalue"
- 如何修复输出日志中的"EnableInput can only be specified on a Pawn for its Controller"错误
- _BitScanForward64 can not be found
- C++复制函数重载导致"must be a nonstatic member function"错误
- 通过分隔符分隔包含 UTF-16 BE 文本的uint8_t数组
- C++ 错误:"array must be initialized with a brace-enclosed initializer"
- 使用 QMediaPlayer 时出现"QWidget::paintEngine: Should no longer be called"
- C++ 被迫做一个奇怪的演员表来摆脱"expression should be a modifiable lvalue"
- 为什么CPPCHECK说"Function parameter should be passed by reference"?
- 禁止从模板类的库标头中"Base class ‘class X’ should be explicitly initialized in the copy constructor"
- 来自 MSDN 的 InternetGetConnectedState 和"it should not be used from a service"声明
- 无法在Qt小部件上绘画,显示错误"paintEngine: Should no longer be called"
- 错误 C2259:无法实例化抽象类;或"how exactly should i be using virtual functions here?"
- 为什么 gcc 4.8.1 给我">> should be > > within a nested templated list"错误?这不是在 C++11 中修复的吗?
- 模板中的模板:为什么"`>>' should be `> >' within a nested template argument list"