我需要创建一个类型擦除模式,它允许检索从给定基类继承的所有包含的对象。据我所知,像boost :: any这样的流行类型擦除只有在请求和包含的类完全匹配时才允许使用any_cast检索对象,因此它不符合我的需要。
我可以用模板类解决问题,模板类模仿模板参数的继承关系。例如,TemplateClass<Derived>
应为TemplateClass<Base>
的子项,以便以下示例有效:
// Suppose all clases have virtual destructors so that vtable and RTTI info are available
class ObjectWrapperBase {
}
template<class DataType>
class ObjectWrapperT: public ObjectWrapperBase {
public:
ObjectWrapperBase(T* ptr): dataObjPtr(ptr){}
DataType *dataObjPtr;
}
class Base{}
class Derived: public Base{}
class NotDerivedFromBase{}
int main(){
std::vector<ObjectWrapperBase*> v;
v.push_back(new ObjectWrapperT<Base>(new Base));
v.push_back(new ObjectWrapperT<Derived>(new Derived));
v.push_back(new ObjectWrapperT<NotDerivedFromBase>(new NotDerivedFromBase));
// Now suppose I want to retrieve all the Base and children objects in v
// If ObjectWrapperT<Derived> is a child of ObjectWrapperT<Base> I can write:
for(int i = 0; i < v.size(); i++){
ObjectWrapperT<Base> *wPtr = dynamic_cast<ObjectWrapperT<Base>*>(v[i]);
if(wPtr){
Base *basePtr = wPtr->dataObjPtr;
}
}
}
是否有实现此行为的模式?或最终另一种解决方案 感谢。
答案 0 :(得分:1)
你无法完全按照自己的意愿行事,但你可以通过模板和操作员获得更接近的东西 作为一个最小的工作示例:
#include<type_traits>
template<typename D>
struct S {
S(D *d): d{d} {}
template<typename B, typename = std::enable_if_t<std::is_base_of<B, D>::value>>
operator S<B>() {
return {d};
}
private:
D *d;
};
struct B {};
struct D: B {};
struct A {};
int main() {
S<D> sd{new D};
S<B> sb = sd;
// S<A> sa = sd;
}
如果您将评论切换到最后一行,则A
不会再编译,而B
不是{{1}}的基础。
答案 1 :(得分:0)
我不知道你是否正在寻找它,但你可以这样做:
template <typename T>
class Derived : public T
{
};
然后使用名为Base
的母类来实例化它:
Derived<Base> object;
您最终会从Base
:
class Derived : public Base
{
};