C++继承与抽象函数实现

标签 c++ inheritance polymorphism virtual abstract

我遇到了 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(...);
}

基本上我是在继承 Action.h 的类 MoveAction.h 中实现 doAction()。但是,当我执行以下操作时:

Actor.cpp:

...
vector<Action> Actor::getActions(...) {
    vector<Action> actions = vector<Action>();

    actions.push_back(MoveAction(...));
    ...

    return actions;
}

我使用了一个 Action vector ,这样以后的 Action 类型(例如 AttackAction)就可以添加到这个 vector 中,我需要做的就是调用 action.doAction() 让它执行 Action 。但是,执行上述操作会给我 cannot instantiate abstract class 错误..

如果我将代码更改为:

...
vector<MoveAction> Actor::getActions(...) {
    vector<MoveAction> actions = vector<MoveAction>();

    actions.push_back(MoveAction(...));
    ...

    return actions;
}

它工作正常(注意所有类型都更改为 MoveAction),但是这显然会停止任何可扩展性选项。

有人有什么想法吗?我觉得我错过了一些非常明显的东西。

谢谢!

最佳答案

您不能拥有 Action 类型的对象 vector ,即:

vector<Action>

因为抽象类不能有实例。但是,您可以拥有指向抽象类的指针 vector 。

vector<Action*>

这样多态行为将被保留。注意:存储 Action 而不是 Action* 将是一个错误,即使它不是编译错误,因为您将面临 slicing then 。还记得在处理原始指针时正确处理内存管理。您可以使用某种 handle 指针来缓解内存问题: std::shared_ptrboost::shared_ptr 或类似的。通过这种方式,您将引入一点点效率开销,但只要您是初学者,强烈建议您这样做。不要担心这个,因为这可能是预优化。首先,您需要一个不会泄漏内存的正确、有效的代码,然后您可以随时调整(优化)。

C++ 标准 n3337 § 10.4/1 抽象类

The abstract class mechanism supports the notion of a general concept, such as a shape, of which only more concrete variants, such as circle and square, can actually be used. An abstract class can also be used to define an interface for which derived classes provide a variety of implementations.

C++ 标准 n3337 § 10.4/2

An abstract class is a class that can be used only as a base class of some other class; no objects of an abstract class can be created except as subobjects of a class derived from it. A class is abstract if it has at least one pure virtual function. [ Note: Such a function might be inherited: see below. — end note ] A virtual function is specified pure by using a pure-specifier (9.2) in the function declaration in the class definition. (...)

关于C++继承与抽象函数实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23789655/

相关文章:

c++ - 这两段代码有什么区别吗? (临时变量)

Java 泛型 : create a general method operating on parent classes

c++ - 为什么使用虚拟表而不是函数指针?

compiler-errors - OCaml 变量类型泛化

c++ - 多态显式模板实例化

java - Java 中的动态方法绑定(bind)

c++ - 快速排序算法代码

c++ - Visual Studio 2010 - 独立函数中的链接器错误

c++ - 并行化 for 循环不会带来性能提升

ios - 在继承中我们可以通过 viewDidLoad