Lets say I've got:
class Base {/*...*/}
class Derived1: public Base {/*...*/}
class Derived2: public Base {/*...*/}
..and I've got:
class SomeClass {
public:
template<typename DerivedType>
DerivedType GetDerived();
private:
vector<Base*> m_classes;
}
In the GetDerived()
function I iterate trough the m_classes vector and I would like to do something like:
if(m_classes[i] == DerivedType) {
return m_classes[i];
}
...and lets assume we know that one of the objects in the m_classes will contain a 'DerivedType' object.
Example:
m_classes[2] = Base* BasePtr = new Derived1;
.. in this case I'd like to use the GetDerived function like this:
GetDerived<Derived1>();
.. and this should return m_classes[2]
How do I do this? How do I compare a base pointer object with a derived class type? More exactly, how should the GetDerived()
function look like?
Storing objects of different classes in the same container when you need to treat them differently is a bad idea.
C++ however has what you're looking for, this time. dynamic_cast<B>(a)
will try and convert a
(whatever it is) to type B
. If the runtime classes do not match, it will return nullptr
.
Here is how you could write GetDerived
:
template <class Tsearched>
Tsearched *GetDerived() {
for(auto c : m_classes) {
if(Tsearched *ptr = dynamic_cast<Tsearched*>(c))
return ptr;
}
return nullptr;
}
Or, with the help of a standard algorithm :
template <class Tsearched>
Tsearched *GetDerived() {
auto found = std::find_if(m_classes.begin(), m_classes.end(), [](Base *ptr) {
return dynamic_cast<Tsearched*>(ptr);
});
return found == m_classes.end() ? nullptr : static_cast<Tsearched*>(*found);
}
Let me repeat, however, that there is a design issue in here. RTTI (what dynamic_cast
uses) is neither elegant, nor fast.
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