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.
精彩评论