对模板使用dynamic_cast
using dynamic_cast with templates
在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
派生的(在这种情况下,如果ChildClass
已经成功分配,dynamic_cast
将始终返回non-NULL
)。
但是是否有办法确保ChildClass
在编译时(模板扩展时间)从ParentClass
派生?
在c++中,模板和继承是不相关的,但我可能遗漏了一些明显的东西。
的限制不幸的是,代码应该在旧的编译器上编译(例如,Visual Studio 6附带的c++实现),这排除了任何新的扩展,如C++11
-features
您可以使用std::is_base_of
:
constexpr bool is_base = std::is_base_of<ParentClass, ChildClass>::value;
当ChildClass
不是从ParentClass
派生的时候,你可以在static_assert
中使用这个来表示编译器错误。
static_assert(std::is_base_of<ParentClass, ChildClass>::value,
"ParentClass is not base of ChildClass");
如果你没有c++ 11的支持,你可以使用boost::is_base_of
和BOOST_STATIC_ASSERT
如果"Derived"继承自"Base",那么"Derived"类型的指针可以赋值给指向"Base"类型的指针。例如:
void AssignToBase(Derived* derived) {
Base* base = derived;
}
…以上成功编译证明了"Derived"继承自"Base"。您可以将它与SFINAE和静态断言(无论是在c++ 11中还是使用Boost的静态断言机制)结合使用,以验证派生类是否继承自父类。正如juanchopanza所指出的,c++ 11提供了一个简单的std::is_base_of<>类型特征类,您可以使用它来测试这种继承关系。
- 如何理解C++标准N3337中的expr.const.cast子句8
- C++Cast运算符过载
- 在成员dynamic_bitset上使用 boost::from_block_range 时出错,但在本地dynamic
- C++类中的二维"dynamic"数组?
- 错误:"cast"未命名类型void setCastDescription(std::string
- 通过使用 const-cast 的非常量引用来延长临时的寿命
- "(void) cast"与功能有什么区别 "__attributes__"来沉默未使用的参数警告?
- protobuf in C++ with dynamic binding for google::protobuf::M
- 警告的原因是什么:"when type is in parentheses, array cannot have dynamic size"?
- C++:"Expected '(' for function-style cast or type construction"错误
- 为什么选择 g++ 给予者:"error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]"
- CUDA 错误:"dynamic initialization is not supported for __device__, __constant__ and __shared__ variabl
- Gtk+ g_signal_connect() 和 C++ lambda 会导致"invalid cast"错误
- 如何修复'The procedure entry point SDL_RWclose could not be located in the dynamic link library'
- Shared_ptr cast vs static_cast speed
- 在 iOS 上使用 Aruco 构建 OpenCV 时"Functional-style cast from id to double is not allowed"
- "The ordinal 344 could not be located in the dynamic link library"
- 覆盖 CAST 运算符(我认为它被称为向下转换)
- Dynamic Cast C++ Fail
- dynamic-cast-c++dynamic_cast错误处理