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

Tra*_*iew 1 c++ polymorphism virtual inheritance 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

MoveAction.cpp:

#include "MoveAction.h"

MoveAction::MoveAction(...) : Action() {
    ...
}

/* Do action */
void MoveAction::doAction() {
    ...
    setTile(...);
}
Run Code Online (Sandbox Code Playgroud)

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

Actor.cpp:

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

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

    return actions;
}
Run Code Online (Sandbox Code Playgroud)

我使用了一个向量,Action然后AttackAction可以将未来的Action类型(例如)添加到此向量中,我需要做的就是调用action.doAction()它来执行操作.但是上面的操作给了我cannot instantiate abstract class错误..

如果我将代码更改为:

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

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

    return actions;
}
Run Code Online (Sandbox Code Playgroud)

它工作正常(请注意所有类型的更改MoveAction),但这显然会阻止任何可扩展性选项.

有人有主意吗?我觉得我错过了一些非常明显的东西.

谢谢!

4pi*_*ie0 6

你不能拥有类型对象的向量Action,即:

vector<Action>
Run Code Online (Sandbox Code Playgroud)

因为抽象类不能有实例.但是,您可以使用指向抽象类的指针.

vector<Action*>
Run Code Online (Sandbox Code Playgroud)

这样就可以保留多态行为.注:存储Action,而不是Action*本来即使它不是编译错误,因为你将面临一个错误切片 然后.还要记住在处理原始指针时正确处理内存管理.您可以使用某种句柄来缓解内存问题:std :: shared_ptr,boost :: shared_ptr或类似的.这样你就会引入一点点效率开销,但只要你是初学者就强烈建议这样做.不要担心这个,因为这可能是预优化.首先,您需要一个没有泄漏内存的正确工作代码,然后您可以随时调整(优化).

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

抽象类机制支持一般概念的概念,例如形状,其中实际上只能使用更具体的变体,例如圆形和方形.抽象类也可用于定义派生类为其提供各种实现的接口.

C++标准n3337 § 10.4/2

抽象类是一个只能用作其他类的基类的类; 除了作为派生自它的类的子对象之外,不能创建抽象类的任何对象.如果一个类至少有一个纯虚函数,则它是抽象的.[注意:这样的功能可能会被继承:见下文. - 结束注释]通过在类定义中的函数声明中使用纯说明符(9.2)来指定虚函数.(......)