LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Identify class type (https://www.linuxquestions.org/questions/programming-9/identify-class-type-551477/)

Ephracis 05-05-2007 07:28 AM

Identify class type
 
I have a vector with a number of items, which are of two or more different class types (RaptorLayoutBox, RaptorLayoutSearchBox and RaptorLayoutPlasmoidArea). They all inherit from the same abstract class (RaptorLayoutAbstractItem).

I have three functions which searches the vector for a hit and should return the match. For example a searchBox() function that will search for a item of type RaptorLayoutSearchBox and return it.

I am trying to use typeid() to identify the type of the item. But it doesn't work too well. All items identifies as "24RaptorLayoutAbstractItem".

Here is the code, there is a lot of qt in there but it should make no difference. I was using QVector but I have changed it to std::vector, hoping that it would help. But no luck. Anyway:
Code:

        std::vector<RaptorLayoutAbstractItem*> *v = new std::vector<RaptorLayoutAbstractItem*>();
        v->push_back(new RaptorLayoutSearchBox("mama", this));
        v->push_back(new RaptorLayoutPlasmoidArea("papa", this, 0, 0));

        QString str1, str2;
        str1.append("Item 0 is of type ").append(typeid(*(v->at(0))).name()).append(".\n");
        str2.append("Item 1 is of type ").append(typeid(*(v->at(1))).name()).append(".\n");
        QMessageBox::information(0, "Vector", QObject::tr("%1\n%2").arg(str1).arg(str2));

Result:
"Item 0 is of type 24RaptorLayoutAbstractItem.

Item 1 is of type 24RaptorLayoutAbstractItem."

Expected result:
"Item 0 is of type ##RaptorLayoutSearchBox.

Item 1 is of type ##RaptorLayoutPlasmoidArea."

(## = some number)

elsheikhmh 05-05-2007 09:03 AM

typeid works correctly with "polymorphic classes". The following from ISO C++ Standard 5.2.8:
Quote:

When typeid is applied to an lvalue expression whose type is a polymorphic class type (10.3), the result refers to a std::type_info object representing the type of the most derived object (1.8) (that is, the dynamic type) to which the lvalue refers. If the lvalue expression is obtained by applying the unary * operator to a pointer67) and the pointer is a null pointer value (4.10), the typeid expression throws the std::bad_typeid exception (18.6.3).
They key here that your base class is not polymorphic unless you have a virtual function.

Are you sure that RaptorLayoutAbstractItem contains a virtual destructor? Check this:
Code:

#include <iostream>
#include <vector>
#include <typeinfo>

using namespace std;

class RaptorLayoutAbstractItem {
public:
        virtual ~RaptorLayoutAbstractItem() {} // <--- comment this and you will see
};

class RaptorLayoutSearchBox : public RaptorLayoutAbstractItem {
};

class RaptorLayoutPlasmoidArea : public RaptorLayoutAbstractItem {
};

int main ()
{
        vector<RaptorLayoutAbstractItem*> *v = new vector<RaptorLayoutAbstractItem*>();

        v->push_back(new RaptorLayoutAbstractItem()); // AbstractItem :)
        v->push_back(new RaptorLayoutSearchBox());
        v->push_back(new RaptorLayoutPlasmoidArea());

        cout << typeid(*(v->at(0))).name() << endl;
        cout << typeid(*(v->at(1))).name() << endl;
        cout << typeid(*(v->at(2))).name() << endl;

        return 0;
}

The output is:
Quote:

24RaptorLayoutAbstractItem
21RaptorLayoutSearchBox
24RaptorLayoutPlasmoidArea
-Mustafa


All times are GMT -5. The time now is 08:55 AM.