yegor256
yegor256

Reputation: 105043

How to check the type name of an object in derived classes?

This is my code:

class Base { /* something */ };
class Derived : public Base { /* something */ };
vector<Base*> v; // somebody else initializes it, somewhere
int counter = 0; 
for (vector<Base*>::iterator i=v.begin(); i!=v.end(); ++i) {
  if (typeof(*i) == "Derived") { // this line is NOT correct
    counter++;
  }
}
cout << "Found " << counter << " derived classes";

One line in the code is NOT correct. How should I write it properly? Many thanks in advance!

Upvotes: 0

Views: 545

Answers (6)

UncleBens
UncleBens

Reputation: 41333

The names of typeid are implementation-defined and you shouldn't make assumptions about them. However, you could compare two typeid's.

if typeid(**i) == typeid(Derived)

Generally it would be considered a bad design (but if the purpose is just to write a not very practical program to count instances of Derived, it's just fine).

Note that this also requires Base to have a vtable (virtual functions and/or destructor), because non-polymorphic types just don't have a dynamic type which typeid checks (that is, they would all be instances of Base as far as typeid is concerned).

If you don't have any virtual functions, then you'll need to emulate this yourself. For example, if you like string comparisons and don't mind the overhead, add a field to Base that each type will fill out in its constructor and compare those. Otherwise use a unique integral identifier for each subtype etc.

Upvotes: 5

dmaestro12
dmaestro12

Reputation: 903

I think you want:

for (...) {
   if (dynamic_cast<Derived*>(*i)) {
     counter++;
   }
}

dynamic_cast<> tries to convert the base class pointer to a derived-class pointer. If the object is of the derived type (or a subclass of it), the correct pointer is returned. If it is not that derived type it returns 'nil' to indicate that the conversion cannot be done successfully.

Upvotes: 0

Konrad Rudolph
Konrad Rudolph

Reputation: 545488

You can either use typeid (include <typeinfo>):

if (typeid(**i) == typeid(Derived))

or you can use a dynamic cast:

if (dynamic_cast<Derived*>(*i) != 0)

but both codes should generally be avoided in favour of a virtual function that is called and that is overridden to perform the appropriate action for each type.

Upvotes: 1

anon
anon

Reputation:

Use dynamic_cast:

if ( dynamic_cast <Derived*>( *i) ) { 
    counter++;

For this to work, you will need to give your base class at least one virtual function - it really needs a virtual destructor anyway.

Upvotes: 5

Jacob
Jacob

Reputation: 34601

I think typeof is only available in C#.

The SO post "How to typeof in C++" may be of use ...

Update: This may be of use:

The typeof operator, AFAIK, was a GCC extension. It no longer works on templated objects as of GCC 3.2.3. Bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9459

Release changes: http://www.gnu.org/software/gcc/gcc-3.2/changes.html

Currently GCC seems to have a really hard time determining the type of template functions even in legitimate circumstances...

And I think GCC supports the __typeof__ operator.

And as others have stated, I guess you can use typeid as a replacement.

Upvotes: 0

a1ex07
a1ex07

Reputation: 37354

Take a look on typeid operator.

In general, it's considered a bad idea to use it.

Upvotes: 0

Related Questions