使用带模板的动态强制转换 在C++中实现基于模板的工厂时,我创建了下面的分配器> /Cux>函数来实例化给定的子类: 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; } 模板 父类*分配器(){ ChildClass*child=新的ChildClass(); 父类*父类=动态\u转换(子级); if(NULL==父级){ 删除儿童; 返回NULL; } 返回父母; }
一切正常,但是当通过静态代码分析工具运行代码时,比如使用带模板的动态强制转换 在C++中实现基于模板的工厂时,我创建了下面的分配器> /Cux>函数来实例化给定的子类: 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; } 模板 父类*分配器(){ ChildClass*child=新的ChildClass(); 父类*父类=动态\u转换(子级); if(NULL==父级){ 删除儿童; 返回NULL; } 返回父母; },c++,templates,inheritance,dynamic-cast,C++,Templates,Inheritance,Dynamic Cast,一切正常,但是当通过静态代码分析工具运行代码时,比如delete子类行被标记为逻辑死代码 我执行运行时检查的原因是断言ChildClass来自ParentClass static_assert(std::is_base_of<ParentClass, ChildClass>::value, "ParentClass is not base of ChildClass"); 现在我了解到,在模板扩展期间,编译器已经知道ChildClass是否派生自Pare
delete子类代码>行被标记为逻辑死代码
我执行运行时检查的原因是断言ChildClass
来自ParentClass
static_assert(std::is_base_of<ParentClass, ChildClass>::value,
"ParentClass is not base of ChildClass");
现在我了解到,在模板扩展期间,编译器已经知道ChildClass
是否派生自ParentClass
,并且dynamic\u cast
仅在运行时进行计算
因此,如果子类
确实是从父类
派生的,则运行时检查在逻辑上是死代码(在这种情况下,如果子类
已成功分配,动态转换
将始终返回非空
)
但是有没有办法确保编译时(模板扩展时)从父类
派生出子类
<>,模板和继承在C++中是无关的,但是我可能缺少明显的东西。
限制
不幸的是,代码应该在较旧的编译器(例如Visual Studio 6附带的C++实现)上编译,这排除了任何较新的扩展,如C++11
-功能可以使用:
如果不支持C++11,则可以使用和。如果“派生”继承自“Base”,则可以将“派生”的指针指定给指向“Base”的指针。即:
。。。以上的成功编译证明,“派生”继承自“基”。您可以将其与SFINAE和静态断言(无论是在C++11中还是使用Boost的静态断言机制)结合使用,以验证派生类是否继承自父类。正如juanchopanza所指出的,C++11提供了一个简单的std::is_base_类型特征类,您可以使用它来测试这种继承关系。如果您的编译器和库支持C++11,您可以使用它。@JoachimPileborg很好,但是我希望能够使用VisualStudio-6(原文如此!)对我的代码进行遗留编译,所以它甚至不是C++98
你应该在你的问题中清楚地说明这些限制。@juanchopanza感谢你的提示,更新了问题你当前的实现将抛出std::bad_alloc
在new
上,如果它不能分配内存,不要给出nullptr
。您应该使用new(std::nothrow)ChildClass()代码>如果您想在失败时获得nullptr
)关于返回值,OP返回的是父项
,它将是一个有效指针或NULL
,因此没有错误。@umläute,你说得对。尽管如此,如果这里有一个早期的“returnnullptr”,阅读起来肯定会更容易。
static_assert(std::is_base_of<ParentClass, ChildClass>::value,
"ParentClass is not base of ChildClass");
void AssignToBase(Derived* derived) {
Base* base = derived;
}