while implementing a template-based factory in C++, i have created the following allocator
function to instantiate a given child class:
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;
}
everything works fine, but when running the code through static code-analysis tools like coverity, the delete child;
line is flagged as logically dead code.
the reason why i do the runtime-check is to assert, that ChildClass
is derived from ParentClass
.
now i understand, that during template expansion the compiler already knows whether ChildClass
is derived from ParentClass
, and that the dynamic_cast
is only evaluated during run-time.
so the run-time check is logically dead code, if the ChildClass
is indeed derived from the ParentClass
(in which case the dynamic_cast
will always return non-NULL
if ChildClass
has been successfully allocated).
but is there a way to ensure that ChildClass
is derived from ParentClass
during compile-time (template expansion time)?
afaik, templates and inheritance are unrelated in C++, but i might be missing something obvious.
unfortunately the code should compile on older compilers (e.g. the C++-implementation that comes with Visual Studio 6) which rules out any newer extension like C++11
-features
While typeid + static_cast is faster than dynamic_cast , not having to switch on the runtime type of the object is faster than any of them. Save this answer.
The dynamic_cast operator can be used to cast to reference types. C++ reference casts are similar to pointer casts: they can be used to cast from references to base class objects to references to derived class objects.
For example, dynamic_cast uses RTTI and the following program fails with the error “cannot dynamic_cast `b' (of type `class B*') to type `class D*' (source type is not polymorphic) ” because there is no virtual function in the base class B.
In C++, dynamic casting is, primarily, used to safely downcast; i.e., cast a base class pointer (or reference) to a derived class pointer (or reference). It can also be used for upcasting; i.e., casting a derived class pointer (or reference) to a base class pointer (or reference).
You can use std::is_base_of
:
constexpr bool is_base = std::is_base_of<ParentClass, ChildClass>::value;
You can use this inside a static_assert
to signal a compiler error when ChildClass
is not derived from ParentClass
.
static_assert(std::is_base_of<ParentClass, ChildClass>::value,
"ParentClass is not base of ChildClass");
If you don't have C++11 support, you can use boost::is_base_of
and BOOST_STATIC_ASSERT
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With