好吧所以我正在尝试创建一个Actor-Behavior系统,而我在使用不完整的类型时遇到了一些麻烦,基本上,当我试图杀死一个Actor时,它告诉我类Actor是一个不完整的类型。 / p>
所以我的结构如下:
Planet-> Vector of all Actors
Actor-> Vector of all Behaviors
Behaviour-> Game Logic
首先,我们有Behavior类,它引用了它的actor(将它添加到其集合中的actor),一个保存其类型的字符串,以及用于游戏逻辑的函数: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类,它包含一个指向其所有行为的唯一指针的向量,一个指向它的Planet的指针,一个唯一的id,一个名称和游戏逻辑函数,用于遍历所有行为并执行游戏逻辑!
// 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类包含一个指向其所有Actors的唯一指针的向量,一个名称以及一个用于其Actors的唯一id生成器:
// 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,内存,向量等内容!但是不包括我创建的文件!
还有一个名为Win的类,它有一个unique_ptr&lt;的集合。行星&gt; 在Public.h中有一个名为win的公共变量(包含在任何地方),每次构建一个Planet时它都被推送到该集合,而Win类有一个指向最后构建的Planet的指针,所以每次一个Actor都是构造,这一行被称为:
{
// other stuff
win.GetCurrentPlanet()->AddActor(this);
}
我测试了这个结构并且它运行成功,我可以有多个行星并从一个跳到另一个,指向Actors的指针没有问题,指向行为的指针也可以正常工作!
现在的问题在于,当我调用KillActor函数时,它正确地遍历所有Actors,它找到了我要杀死的Actor然后当我调用擦除该Actor时它将我发送到文件内存,并告诉我我的程序触发了一个断点:
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;
}