我对此代码有疑问 - 这是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()});
它没有问题:/
答案 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>());
}