我对c ++很新,并尝试实现entity-component-system (ECS)。
我有一个地址IComponent
和一个名为Component
的基类来实现这个界面。基类Component
有许多子类(例如PositionComponent
,VelocityComponent
等。)
我希望Component
的每个子类都有自己的该类实例的静态列表。例如,PositionComponent
应该包含PositionComponent
的所有实例的静态列表。
因为我不想在每个子类中复制相同的代码,所以我将列表放在基类Component
中。但是因为它是静态的,所以子类不会获得它自己的实例,而是使用基类中的列表。
在尝试解决这个问题时,我偶然发现curiously recurring template pattern (CRTP)实现了某种形式的静态多态。
我现在的问题是,当我在PositionComponent
类型的对象上调用destroy时,我在Component::destroy
的最后一行收到以下错误,我尝试将this
分配给{{} 1}}:
pFirstInPool
这可以修复,还是我试图做的,根本不可能按照我的设计方式进行?
以下是代码:
IComponent的的
invalid conversion from 'Component<PositionComponent>* const' to 'PositionComponent*'
组件
class IComponent
{
public:
virtual ~IComponent() {}
virtual void destroy() = 0;
protected:
IComponent() {}
private:
};
PositionComponent
template <typename T>
class Component : public IComponent
{
public:
virtual ~Component() {}
inline Entity* getEntity() { return pEntity; }
static T* create() {
/* returns an object from the list of inactive objects (the pool)
or returns a new object if the pool is empty.
then it adds it to the list of active objects */
T* lpNew;
if ( pFirstInPool == nullptr ) {
lpNew = new T;
}else{
lpNew = pFirstInPool;
if ( lpNew->getNext() != nullptr ) {
lpNew->getNext()->setPrev(nullptr);
pFirstInPool = lpNew->getNext();
}else{
pFirstInPool = nullptr;
}
}
if ( pFirst != nullptr ) {
pFirst->setPrev(lpNew);
}else{
pLast = lpNew;
}
lpNew->setNext(pFirst);
lpNew->setPrev(nullptr);
pFirst = lpNew;
return lpNew;
}
void destroy() {
/* removes an object from the list of active objects
and adds it to the list of inactive objects (the pool) */
if ( this == pFirst ) {
pFirst = pNext;
}
if ( this == pLast ) {
pLast = pPrev;
}
if ( pPrev != nullptr ) {
pPrev->setNext(pNext);
}
if ( pNext != nullptr ) {
pNext->setPrev(pPrev);
}
pPrev = nullptr;
pNext = pFirstInPool;
pFirstInPool = this;
}
inline T* getPrev() { return pPrev; }
inline T* getNext() { return pNext; }
inline void setPrev( T* tpPrev ) { pPrev = tpPrev; }
inline void setNext( T* tpNext ) { pNext = tpNext; }
static inline T* getFirst() { return pFirst; }
static inline T* getLast() { return pLast; }
protected:
Component() : lEnabled(true), pPrev(nullptr), pNext(nullptr) {}
private:
Entity* pEntity;
bool lEnabled;
T* pPrev;
T* pNext;
static T* pFirst;
static T* pLast;
static T* pFirstInPool;
};
template <typename T>
T* Component<T>::pFirst = nullptr;
template <typename T>
T* Component<T>::pLast = nullptr;
template <typename T>
T* Component<T>::pFirstInPool = nullptr;
VelocityComponent
class PositionComponent : public Component<PositionComponent>
{
public:
PositionComponent();
/*...*/
protected:
private:
};