我无法传递从DerivedObject
派生的类DerivedClass
(类BaseClass
的一部分派生自模板类BaseObject
)(模板类的一部分{ {1}})作为模板类BaseClass
的模板参数。
这样,Base和Derived类都可以访问对象池,该对象池可以包含派生对象。这听起来有点令人困惑,所以这是一个例子:
BaseClass
以上是基类实现。
template <class TDerivedClass, class TDerivedObject>
class BaseClass
{
protected:
class BaseObject
{
// Class implementation
}
void foo()
{
static_cast<TDerivedClass*>(this)->foo();
}
std::vector<TDerivedObject*> m_objectPool;
};
上面的错误是由类定义的第一行引起的:
error C2065: 'DerivedObject' undeclared identifier
有办法做到这一点吗?如果没有,是否有更好的解决方案可以提供相同/相似的功能?
答案 0 :(得分:5)
此时
class DerivedClass : public BaseClass<DerivedClass, DerivedClass::DerivedObject>
编译器没有看到DerivedClass::DerivedObject
,因此您收到未声明的标识符错误。由于尚未看到它们的类型,因此无法将其用作模板参数。您没有为DerivedClass
获得一个,因为您已将DerivedClass
声明为class
。
您可以更改基类并在其中存储std::vector<BaseObject*>
,如果您这样做,则可以将代码更改为:
template <class TDerivedClass>
class BaseClass
{
protected:
class BaseObject
{
// Class implementation
};
void foo()
{
static_cast<TDerivedClass*>(this)->foo();
}
std::vector<BaseObject*> m_objectPool;
};
class DerivedClass : public BaseClass<DerivedClass>
{
protected:
class DerivedObject : public BaseObject
{
// Class implementation
};
void foo()
{
// Method implementation
}
};
答案 1 :(得分:1)
从您的示例代码中,我得到的印象是您希望为不同的基类提供不同的实现。使用模板有什么特殊原因吗?如果没有,您可以使用经典多态:
class BaseClass
{
class BaseObject {};
virtual ~BaseClass() {} // <- do not forget to provide virtual dtor!
virtual void foo() = 0;
std::vector<BaseObject*> m_objectPool;
};
class DerivedClass : public BaseClass
{
class DerivedObject : public BaseObject {/*...*/};
virtual void foo(){/*...*/}
};
同样,BaseObject将提供虚拟或纯虚函数 - 如您所愿。
但是,有一件事你会失去这种方式:保证在向量中始终存在一个特定BaseObject子类型的对象。如果这对您很重要,则可以保护池,并且只允许通过DerivedClass添加新的BaseObject。如果这不适用,我可能会想到BaseClass中的另一个解决方案。答案 2 :(得分:1)
这是做出类似于所要求的事情的一种方式:
#include <vector>
using std::vector;
template <class TDerivedClass, class TDerivedObject>
class BaseClass
{
public:
class BaseObject
{
// Class implementation
};
protected:
// void foo()
// {
// static_cast<TDerivedClass*>(this)->foo();
// }
// std::vector<TDerivedObject*> m_objectPool;
};
class DerivedClass;
class DerivedObject : public BaseClass<DerivedClass, DerivedObject>::BaseObject
{
// Class implementation
};
class DerivedClass : public BaseClass<DerivedClass, DerivedObject>
{
public:
void foo()
{
// Method implementation
}
};
答案 3 :(得分:0)
如果您不介意将DerivedObject结构与DerivedClass分开,您可以执行以下操作:
template <class T>
struct ObjectTypeTrait
{
static_assert(sizeof(T) == 0, "undefined trait");
};
template <class TDerivedClass>
class BaseClass
{
protected:
class BaseObject
{
// Class implementation
};
void foo()
{
static_cast<TDerivedClass*>(this)->foo();
}
std::vector<typename ObjectTypeTrait<TDerivedClass>::obj*> m_objectPool;
};
class DerivedClass;
class DerivedObject
{
// Class implementation
};
template<>
struct ObjectTypeTrait<DerivedClass>
{
using obj = DerivedObject;
};
class DerivedClass : public BaseClass<DerivedClass>
{
protected:
void foo()
{
// Method implementation
}
};
我不认为这是一个非常出色的解决方案,但你可以得到这个想法 - 使用类型特征或typedef