views:

228

answers:

2

If I understand correctly, typeid can determine the actual type in polymorphism, while typeof cannot.

Is it also true that their returns are used for different purposes: the return of typeof is used as type keyword that can define variable, but the return of typeid cannot?

Is there any way to both get the actual type for polymorphism and use the return as type keyword to define another variable? I hope to get the derived class type from a pointer pointing to the base class and define a variable of or a pointer to the derived class. Something like:

baseclass *p = new derivedclass  
typexxx(*p) *pp = dynamic_cast<typexxx(*p) *> (p); 
// would like to convert the pointer from pointing to a base class 
// to its derived class

Thank you very much!

+4  A: 

c++0x will have decltype which can be used like this:

int someInt;
decltype(someInt) otherIntegerVariable = 5;

but for plain old c++, unfortunately, no.

I suppose that decltype won't really be much help either though since you want the polymorphic type, not the declared type. The most straight forward way to do what you want is to attempt to dynamic cast to a particular type and check for NULL.

struct A {
    virtual ~A() {}
};
struct B : public A {};
struct C : public A {};

int main() {
    A* x = new C;
    if(B* b_ptr = dynamic_cast<B*>(x)) {
        // it's a B
    } else if(C* c_ptr = dynamic_cast<C*>(x)) {
        // it's a C
    }
}
Evan Teran
Thanks Evan! But sometimes I need to determine the type at runtime such as via command line argument. See my post here http://stackoverflow.com/questions/1984492/runtime-determine-type-for-c, you will understand.
Tim
`if (B* b_ptr = dynamic_cast<B*>(x))` and no need for the either the union or mis-scoped variables. Plus you can write more natural `else if` instead of `else { ... if ... }`
Roger Pate
@Roger: you learn something new every day, I was unaware that you could declare variable inside an if statement. and result in appropriate scope. I'll update my answer.
Evan Teran
+3  A: 

Assuming a hierarchy A <- B <- C

A * p = new AorBorC;   // create new object of some sort

if ( dynamic_cast <C*>(p) ) {
  C * c = dynamic_cast <C*>(p);
  c->CFunc();
}
else if ( dynamic_cast <B*>(p) ) {
  B * b = dynamic_cast <B*>(p);
  b->BFunc();
}
else if ( dynamic_cast <A*>(p) ) {
  A * a = dynamic_cast <A*>(p);
  a->AFunc();
}

Where AFunc, BFunc, CFunc are specific to their respective classes, and not virtual. Obviously, this can be optimised somewhat.

anon
`if (C* c = dynamic_cast<C*>(p)) { /*use c*/ }` No need to cast twice.
Roger Pate
Quite - I was trying to make things clearer by being long-winded.
anon