开发者

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 (v开发者_运维知识库ector<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!


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.


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.


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.


Take a look on typeid operator.

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


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜