如何使用模板函数的多态性来创建从模板派生的类?

  • 本文关键字:派生 创建 多态性 何使用 函数 c++
  • 更新时间 :
  • 英文 :


我想实现以下代码:

template<class ManagerBase>
class ManagerA : public ManagerBase {};
template<class ManagerBase>
class ManagerB : public ManagerBase {};
class Base {
public:
template<typename ManagerBase>
virtual ManagerBase* CreateManager() const = 0;
};
class A : public Base{
public:
template<typename ManagerBase>
virtual ManagerBase* CreateManager() const { return new ManagerA<ManagerBase>; }
};
class B : public Base{
public:
template<typename ManagerBase>
virtual ManagerBase* CreateManager() const { return new ManagerB<ManagerBase>; }
};
class SomeManagerBase {};
int main() {
Base* pPolymorphic = new A;
SomeManagerBase* pBase = pPolymorphic->CreateManager<SomeManagerBase>();
}

但是由于c++似乎不允许将虚函数与模板混合,我该如何实现呢?我已经考虑过在基类上有一个switch而不是一个纯函数,所以它会从基本身调用正确的函数,但这似乎不是一个好方法,因为每次我创建一个从Base派生的新类,我将不得不改变这个函数,所以我期待有人会更好地了解这里可以做些什么。

您想要做什么并不清楚,因为如果您想要复制仅给定其基类的对象,则有效的返回类型将不得不依赖于运行时值。一种可能性是创建一个非模板虚函数,并从模板包装器调用它。例如:

#include <cassert>
#include <typeinfo>
template<class ManagerBase>
class ManagerA : public ManagerBase {};
template<class ManagerBase>
class ManagerB : public ManagerBase {};
class Base {
virtual Base* CreateManagerImpl() const = 0;
public:
virtual ~Base() {}
template<typename T> T* CreateManager() const {
if (!dynamic_cast<const T*>(this))
return nullptr;
return static_cast<T*>(CreateManagerImpl());
}
};
class A : public Base {
public:
Base* CreateManagerImpl() const override { return new ManagerA<A>; }
};
class B : public Base {
public:
Base* CreateManagerImpl() const override { return new ManagerA<B>; }
};
int
main()
{
Base *pa = new A;
Base *pb = pa->CreateManager<A>();
Base *pc = pa->CreateManager<B>();
assert(pb);
assert(!pc);
}

但请注意,如果请求错误的类型,该函数将失败并返回NULL。

现在请注意,您所要求的是能够交换任意基类型,如果在编译时没有类型信息,则无法做到这一点。也许您可以重新编写代码,只使用模板,在这种情况下,每个类型组合都有一个版本的函数。但是在你写多态代码的时候,关键是内存中完全相同的指令将处理所有类型,所以没有办法创建一个依赖于你在编译时没有的类型的新类型(即Base *的完全派生类型)。

最新更新