无法实例化抽象类c ++

时间:2017-03-18 09:32:06

标签: c++ class abstract

我对此代码有疑问 - 这是taskData:

static std::map<int8_t, std::vector<Task>> taskData;

并且存在问题:

taskData.emplace(pi::enumerations::taskManager::taskCategory_t::SECURITY, std::vector<Task>{FirefightingTask()});

FirefightingTask:

#pragma once

#include "Task.hpp"

namespace mc
{
    class FirefightingTask :public Task
    {
    public:

        FirefightingTask( uint8_t category = 0, uint8_t kind = 0, NPC* npc = nullptr );

        virtual bool act() override;
    };
}

任务:

#pragma once

#include "engine/Config.hpp" 

#include <queue>

class NPC;

namespace mc
{
    //Task
    //Represents a task for AI object
    class Task
    {

    public:
        Task(uint8_t category = 0, uint8_t kind = 0, NPC* npc = nullptr );

        uint8_t GetCategory()
        {
            return category;
        }

        uint8_t GetKind()
        {
            return kind;
        }

        bool operator==( const Task& second )
        {
            return this->kind == second.kind;
        }

        bool inProgress()
        {
            return doing;
        }

        virtual bool act() = 0;

    private:

        bool doing;

        const int8_t category;

        const int8_t kind;

        NPC* owner;
    };
}

,错误是:

  

错误C2259&#39; mc ::任务&#39;:无法实例化抽象类

我真的不知道为什么会收到此错误。当我删除这一行时:

        taskData.emplace(pi::enumerations::taskManager::taskCategory_t::SECURITY,std::vector<Task>{FirefightingTask()});

它没有问题:/

3 个答案:

答案 0 :(得分:5)

罪魁祸首是std::vector<Task> - 您无法创建Task的向量,因为Task是抽象的。

您需要使用指针向量。

答案 1 :(得分:0)

std :: vector是不允许的,因为它会创建类“Task”的对象,因为你的“act”方法是抽象的。 请注意,使用std :: make_shared的其他答案的解决方案也不会起作用,因为make_shared会尝试创建“任务”的实例。 您应该尝试使用make_shared&lt;创建firefightingTask。 FirefightingTask&GT;()

另一个注意事项:您正在使用Task作为虚拟基类,因此您应该考虑使用虚拟析构函数。

答案 2 :(得分:0)

Task是抽象的,所以不能有它的实例。 std::vector包含并拥有其值类型的实例。因此,std::vector抽象类型是不可能的,并且没有意义。你不能包含和拥有一些不存在的东西。这与std::vector<int>std::vector<std::string>std::vector<FirefightingTask>等向量的根本区别在于。

向量内的对象的动态类型应该是其他东西(即FirefightingTask),这没有任何帮助。只有静态类型与编译器相关。

然而,

指针可以存在。他们满足将他们放入std::vector所需的所有条件。他们指出的内容与std::vector无关。我们的想法是,它们静态地指向Task并动态指向FirefightingTask个实例(或其他具体子类的实例)。

现在,通常不应手动处理原始指针,因为它的详细和容易出错。幸运的是,C ++提供智能指针类来防止低级别的内存管理错误。在智能指针方面,std::unique_ptr应该是您的默认选择。这是一个基于代码的简单示例:

#include <vector>
#include <map>
#include <memory>

struct Task { virtual ~Task() = 0; };
struct FirefightingTask : Task {};
Task::~Task() {}

int main()
{
    std::map<int, std::vector<std::unique_ptr<Task>>> taskData;

    // map an empty vector of Task pointers to key 0:
    taskData.emplace(0, std::vector<std::unique_ptr<Task>>());

    // three times in a row, create a FirefightingTask instance
    // directly inside of the previously empty vector at key 0:
    taskData[0].emplace_back(std::make_unique<FirefightingTask>());
    taskData[0].emplace_back(std::make_unique<FirefightingTask>());
    taskData[0].emplace_back(std::make_unique<FirefightingTask>());
}