使用CRTP的模板类中的转换错误无效

时间:2015-04-08 12:50:56

标签: c++ static polymorphism crtp

我对c ++很新,并尝试实现entity-component-system (ECS)

我有一个地址IComponent和一个名为Component的基类来实现这个界面。基类Component有许多子类(例如PositionComponentVelocityComponent等。)

我希望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:
};

0 个答案:

没有答案