Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare class types in C++?

Tags:

c++

types

class

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?

like image 877
Marko Kitonjics Avatar asked Dec 11 '14 21:12

Marko Kitonjics


1 Answers

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.

like image 60
Quentin Avatar answered Sep 29 '22 18:09

Quentin