使用带模板的dynamic_cast

时间:2014-05-06 08:35:52

标签: c++ templates inheritance dynamic-cast

在C ++中实现基于模板的工厂时,我创建了以下allocator函数来实例化给定的子类:

template<class ChildClass, class ParentClass>
ParentClass* allocator() {
   ChildClass *child  = new ChildClass();
   ParentClass*parent = dynamic_cast<ParentClass*>(child);
   if(NULL==parent) {
     delete child;
     return NULL;
   }
   return parent;
}

一切正常,但在通过coverity等静态代码分析工具运行代码时,delete child;行被标记为逻辑死代码

我进行运行时检查的原因是断言,ChildClass派生自ParentClass

现在我理解,在模板扩展期间,编译器已经知道ChildClass是否来自ParentClass,而dynamic_cast仅在运行时进行评估。

所以如果ChildClass确实来自ParentClass,那么运行时检查就是逻辑死代码(在这种情况下dynamic_cast将始终返回non-NULL ChildClass已成功分配。)

但是有没有办法确保ChildClass在编译时(模板扩展时间)从ParentClass派生出来?

afaik,模板和继承在C ++中是无关的,但我可能会遗漏一些明显的东西。

限制

遗憾的是,代码应该在较旧的编译器上编译(例如, Visual Studio 6 附带的C ++实现),它排除了C++11之类的任何新扩展 - 功能

2 个答案:

答案 0 :(得分:7)

您可以使用std::is_base_of

constexpr bool is_base = std::is_base_of<ParentClass, ChildClass>::value;

如果static_assert未来自ChildClass,则可以在ParentClass内使用此信号来表示编译器错误。

static_assert(std::is_base_of<ParentClass, ChildClass>::value,
              "ParentClass is not base of ChildClass");

如果您没有C ++ 11支持,则可以使用boost::is_base_ofBOOST_STATIC_ASSERT

答案 1 :(得分:2)

如果“Derived”继承自“Base”,则可以将指向“Derived”的指针分配给指向“Base”的指针。即:

void AssignToBase(Derived* derived) {
  Base* base = derived;
} 

...上述成功编译证明“Derived”继承自“Base”。您可以将此与SFINAE和静态断言(无论是在C ++ 11中还是使用Boost的静态断言机制)结合使用来验证派生类是否继承自父类。正如juanchopanza所说,C ++ 11提供了一个简单的std :: is_base_of&lt;&gt;类型traits类,可用于测试此继承关系。