我收到cannot instantiate abstract class
错误。现在我知道这有什么影响,但是我不知道我的代码是如何做错的。我在这里,寻求帮助。
我有
Action.h
:
#ifndef ACTION_H
#define ACTION_H
// ===== Dependencies ===== //
#include ...
...
// ===== Classes ===== //
class Action
{
public:
Action();
void set(...);
virtual void doAction() = 0;
};
#endif
MoveAction.h
:
#ifndef MOVE_ACTION_H
#define MOVE_ACTION_H
// ===== Dependencies ===== //
#include ...
...
// ===== Classes ===== //
class MoveAction : public Action
{
public:
MoveAction(...); // Constructor
using Action::set;
void doAction(); // Do action
private:
...
};
#endif
MoveAction.cpp
:
#include "MoveAction.h"
MoveAction::MoveAction(...) : Action() {
...
}
/* Do action */
void MoveAction::doAction() {
...
setTile(...);
}
基本上我在继承doAction()
的班级MoveAction.h
中实施Action.h
。但是,当我执行以下操作时:
Actor.cpp
:
...
vector<Action> Actor::getActions(...) {
vector<Action> actions = vector<Action>();
actions.push_back(MoveAction(...));
...
return actions;
}
我使用了Action
的向量,因此可以将未来的Action类型(例如AttackAction
)添加到此向量中,我需要做的就是调用action.doAction()
来执行它那个行动。但是,执行上述操作会给我cannot instantiate abstract class
错误..
如果我将代码更改为:
...
vector<MoveAction> Actor::getActions(...) {
vector<MoveAction> actions = vector<MoveAction>();
actions.push_back(MoveAction(...));
...
return actions;
}
它工作正常(请注意所有类型的更改为MoveAction
),但这显然会阻止任何可扩展性选项。
有人有什么想法吗?我觉得我错过了一些非常明显的东西。
谢谢!
答案 0 :(得分:6)
您不能拥有Action
类型的对象向量,即:
vector<Action>
因为抽象类不能有实例。但是,您可以使用指向抽象类的指针。
vector<Action*>
这样就可以保留多态行为。注意:即使不是编译错误,存储Action
而不是Action*
也会出错,因为您将面临切片 then。还要记住在处理原始指针时正确处理内存管理。您可以使用某种handle指针来缓解内存问题:std::shared_ptr,boost::shared_ptr或类似问题。这样你就会引入一点点效率开销,但只要你是初学者就强烈建议这样做。不要担心这个,因为这可能是预优化。首先,您需要一个没有泄漏内存的正确工作代码,然后您可以随时调整(优化)。
C ++标准版n3337 § 10.4 / 1抽象类
抽象类机制支持一般概念的概念, 如形状,其中只有更具体的变体,如圆形 和方,实际上可以使用。也可以使用抽象类 定义派生类提供各种各样的接口 的实施方式。
C ++标准版n3337 § 10.4 / 2
抽象类是一个只能用作基类的类 其他一些班级; 无法创建抽象类的对象 除了作为从它派生的类的子对象。一堂课是抽象的 如果它至少有一个纯虚函数。 [注意:这样的功能 可能是遗传的:见下文。 - 结束语]虚拟功能是 通过在函数中使用纯说明符(9.2)来指定pure 类定义中的声明。 (...)
答案 1 :(得分:0)
以下是如何使用std::vector<std::unique_ptr<Action>>
代替std:vector<Action>
的示例:
#include <iostream>
#include <vector>
#include <memory>
class Action {
public:
typedef std::vector<std::unique_ptr<Action>> Ptrs;
Action() { }
virtual void doAction() = 0;
};
class MoveAction : public Action {
public:
MoveAction() { }
void doAction() { std::cout << "MoveAction::doAction" << std::endl;}
};
class Actor {
public:
Action::Ptrs getActions();
};
Action::Ptrs
Actor::getActions() {
Action::Ptrs actions;
actions.emplace_back(new MoveAction());
return actions;
}
int main() {
Actor actor;
Action::Ptrs actions = actor.getActions();
actions.back()->doAction();
}