Reputation: 105043
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
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
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
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
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
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