Ошибка vector.erase, невозможно удалить неполный тип

Итак, я пытаюсь создать систему Actor-Behavior, и у меня возникают некоторые проблемы с неполными типами, в основном, когда я пытаюсь убить Actor, он говорит мне, что класс Actor является неполным типом.

Итак, моя структура выглядит следующим образом:

Planet-> Vector of all Actors
Actor-> Vector of all Behaviors
Behaviour-> Game Logic

Во-первых, у нас есть класс Behavior, который имеет ссылку на своего актера (актер, который добавил его в свою коллекцию), строку, содержащую его тип, и функции, используемые для игровой логики: init (вызывается при запуске) и tick (вызывается каждый кадр):

class Actor;

class Behaviour
{
protected:
Actor* actor;
public:
string type;
Behaviour();
~Behaviour();
virtual void Init(); // virtual because every component needs to override them
virtual void Tick();
}

затем у нас есть класс Actor, который содержит вектор уникальных указателей на все его поведения, указатель на его планету, уникальный идентификатор, имя и игровые логические функции, используемые для циклического прохождения всех видов поведения и выполнения игровой логики!

// Actor.h
class Planet;

class Actor
{
private:
unsigned id;
string name;
vector< unique_ptr< Behaviour > > allBehaviours;
protected:
Planet* planet;
public:
Actor();
~Actor();
void Init(); // Go through all the behaviors and call their Inits and Ticks
void Tick();

template <typename T, typename ...Args>
void AddBehaviour(Args && ...args); // Creates and adds a new Behaviour of type T to the allBehaviours vector

template <typename T>
T& GetBehaviour(std::string type); // Loops through all the Behaviours, and returns the Behaviour whose type is the same as type

// Actor.cpp

#include "Planet.h"#include "Behaviour.h"#include "Actor.h"
// Implement Functions

Это был Actor.h, Actor.cpp реализует эти функции и включает Planet.h, затем Behaviour.h, а затем Actor.h!

Теперь класс Planet содержит вектор уникальных указателей на все свои действующие лица, имя и генератор уникальных идентификаторов для своих действующих лиц:

// Planet.h

class Actor;

class Planet
{
private:
unsigned idCounter = 0;
string name;
vector< unique_ptr< Actor > > allActors;
public:
unsigned GetNewID();
void Init();
void Tick(); // Used to loop through all the Actors

void AddActor(Actor* newActor); // adds a new Actor to the list of all Actors
void KillActor(int id); // loops through all the Actors and when it finds an Actor whose unique id is matching the id variable it erases it from the allActors vector

}

// Planet.cpp

#include "Public.h"#include "Actor.h"#include "Planet.h"
Planet::KillActor(int id){
unsigned i = 0;
for (auto& a : allActors) {
if (a->GetID() == id)
allActors.erase(allActors.begin() + i);
i++;
}
}

// Other Functions

У меня также есть файл Public.h, который включает в себя такие вещи, как iostream, memory, vector и т. Д.! Но не включает файлы, которые я создал!

И есть класс с именем Win, который имеет коллекцию unique_ptr < Планета>
и есть публичная переменная win, которая находится в Public.h (включена везде), каждый раз, когда строится планета, она перемещается в эту коллекцию, а класс Win имеет указатель на последнюю построенную планету, поэтому каждый раз, когда субъект построен, эта строка называется:

{
// other stuff
win.GetCurrentPlanet()->AddActor(this);
}

Я протестировал эту структуру, и она успешно работает, я могу иметь несколько планет и переходить с одной на другую, указатели на актеров работают без проблем, указатели на поведение также работают без проблем!

Теперь проблема заключается в том, что когда я вызываю функцию KillActor, она корректно проходит по всем акторам, находит актера, которого я хочу убить, затем, когда я вызываю стирание этого актера, отправляет меня в файловую память и сообщает, что моя программа сработала точка останова:

void operator()(_Ty *_Ptr) const _NOEXCEPT
{   // delete a pointer
static_assert(0 < sizeof (_Ty),
"can't delete an incomplete type");
delete _Ptr; // Here is the breakpoint, it is trying to delete the Actor I inputed
}
};

Я не понимаю, почему это дает мне такую ​​ошибку, я почти уверен, что у меня есть довольно солидная структура включения и прямого объявления.

РЕДАКТИРОВАТЬ 1:

Итак, я сделал тест, я отключил функцию Tick (сейчас она ничего не делает), и я вызываю KillActor следующим образом:

int main() {

Planet b = Planet("B");

Actor bactor = Actor();

bactor.AddBehaviour<TestA>();

b.KillActor(0); // This still results in the same incomplete type error!

do
{
win.changed = false;
win.GetCurrentPlanet()->Init();
while (win.gameRunning)
{
win.Tick();
//win.GetCurrentPlanet()->Tick(1);
if (win.changed)
break;
}
} while (win.changed);

win.Quit();

return 0;
}

0

Решение

Вы не можете удалить из контейнера, который вы все еще повторяете. Ваша функция killActor имеет неопределенное поведение. Попробуйте стереть удалить как Вот

У вас есть виртуальные функции, но нет виртуального деструктора. Почини это.

0

Другие решения

Других решений пока нет …