使用CRTP的模板类中存在无效转换错误 我对C++是全新的,尝试实现.< /p>
我有一个inferface使用CRTP的模板类中存在无效转换错误 我对C++是全新的,尝试实现.< /p>,c++,static,polymorphism,crtp,C++,Static,Polymorphism,Crtp,我有一个inferfaceIComponent和一个实现inferface的基类Component。基类Component有许多子类(例如PositionComponent,VelocityComponent,等等) 我希望组件的每个子类都有自己的该类实例的静态列表。例如,PositionComponent应该有一个包含所有PositionComponent实例的静态列表 因为我不想在每个子类中复制相同的代码,所以我将列表放在基类组件中。但是因为它是静态的,所以子类不会得到它自己的实例,而是使用
IComponent
和一个实现inferface的基类Component
。基类Component
有许多子类(例如PositionComponent
,VelocityComponent
,等等)
我希望组件的每个子类
都有自己的该类实例的静态列表。例如,PositionComponent
应该有一个包含所有PositionComponent
实例的静态列表
因为我不想在每个子类中复制相同的代码,所以我将列表放在基类组件中。但是因为它是静态的,所以子类不会得到它自己的实例,而是使用基类中的列表
在试图解决这个问题时,我偶然发现了实现某种形式的静态多态性的方法
我现在的问题是,当我对类型为PositionComponent
的对象调用destroy时,我在Component::destroy
的最后一行中得到以下错误,我试图将此
分配给pFirstInPool
:
invalid conversion from 'Component<PositionComponent>* const' to 'PositionComponent*'
组成部分
模板
类组件:公共IComponent
{
公众:
虚拟~Component(){}
内联实体*getEntity(){返回奔腾;}
静态T*create(){
/*从非活动对象列表(池)中返回一个对象
如果池为空,则返回一个新对象。
然后将其添加到活动对象列表中*/
T*lpNew;
if(pFirstInPool==nullptr){
lpNew=新T;
}否则{
lpNew=pFirstInPool;
如果(lpNew->getNext()!=nullptr){
lpNew->getNext()->setPrev(nullptr);
pFirstInPool=lpNew->getNext();
}否则{
pFirstInPool=nullptr;
}
}
如果(pFirst!=nullptr){
pFirst->setPrev(lpNew);
}否则{
pLast=lpNew;
}
lpNew->setNext(pFirst);
lpNew->setPrev(nullptr);
pFirst=lpNew;
返回lpNew;
}
无效销毁(){
/*从活动对象列表中删除对象
并将其添加到非活动对象列表(池)*/
if(this==pFirst){
pFirst=pNext;
}
if(this==pLast){
pLast=pPrev;
}
如果(pPrev!=nullptr){
pPrev->setNext(pNext);
}
如果(pNext!=nullptr){
pNext->setPrev(pPrev);
}
pPrev=零PTR;
pNext=pFirstInPool;
pFirstInPool=这个;
}
内联T*getPrev(){return pPrev;}
内联T*getNext(){return pNext;}
内联void setPrev(T*tpPrev){pPrev=tpPrev;}
内联void setNext(T*tpNext){pNext=tpNext;}
静态内联T*getFirst(){return pFirst;}
静态内联T*getLast(){return pLast;}
受保护的:
Component():lEnabled(true)、pPrev(nullptr)、pNext(nullptr){
私人:
实体*奔腾;
bool-lEnabled;
T*pPrev;
T*pNext;
静态T*pFirst;
静态T*pLast;
静态T*pFirstInPool;
};
模板
T*分量::pFirst=nullptr;
模板
T*组件::pLast=nullptr;
模板
T*组件::pFirstInPool=nullptr;
位置元件
类位置组件:公共组件
{
公众:
位置组件();
/*...*/
受保护的:
私人:
};
速度元件
class VelocityComponent:公共组件
{
公众:
速度组件();
/*...*/
受保护的:
私人:
};
此
具有类型组件*
。您有一些类型为Something*
的指针,并尝试将类型为Component*
的分配给它(此处不考虑cv限定符)。那是不可能的。这就像将类A
分配给类B
,但是B
没有规则将A
转换为B
。谢谢您的回复。我真的不明白为什么这个
会得到组件的类型*
。根据我的理解,它应该是Something*
,因为它说newt
,T
是Something
,但那是lpNew
lpNew
是指向您使用newt
创建的内存的东西<代码>此
是一个指向实例本身的指针,该实例将在其中使用。你在组件的销毁
功能中使用它,因此…啊,我明白了。我现在用Component*
替换了所有出现的T*
,它就可以编译了。非常感谢你的帮助!嗯,它也应该起作用。但我能帮助你真是太好了;)
class IComponent
{
public:
virtual ~IComponent() {}
virtual void destroy() = 0;
protected:
IComponent() {}
private:
};
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;
class PositionComponent : public Component<PositionComponent>
{
public:
PositionComponent();
/*...*/
protected:
private:
};
class VelocityComponent : public Component<VelocityComponent>
{
public:
VelocityComponent();
/*...*/
protected:
private:
};