-
typeid problem
Is there any way to print the name of a derive class with a typeid trick,
because I can only manage to write the root class of a root class pointer?
So it will output "class Base", but I would like to receive "class Derivate"...
I'm sure that there's a way, as derived instances are able to get to the good
class's piece of code when you use virtual methods...
Code:
class Base {};
class Derivate : public Base {};
//main()
Base *Ptr = new Derivate;
std::cout << typeid(Ptr).name();
-
typeid(*Ptr).name()
But that only works if Base contains at least one virtual function.
-
Well, that's funny because I tried this too, and it still didn't worked...
Can you show me something that actually works?
-
Ptr is a pointer to base, hence getting the name of the base class. If you want to get the name of the dynamic type of Ptr, you will have to first cast it to derived with dynamic_cast.
EDIT: Assuming of course your base class has no virtuals. Considering dereferencing the pointer didn't work.
-
I still face a problem as with dynamic cast I have to write the derive type
directly between the <>'s, and I don't want to write the name of the derive
here, because it will seem illogical to ask for a derive name that you already
know about... here's what I'm heading to find:
Code:
std::cout << typeid(cast_to_what_it_was_newed_to(Ptr)).name();
-
Works for me, GCC 4.1
Code:
#include <typeinfo>
#include <iostream>
class Base
{
public:
virtual ~Base() {}
};
class Derived : public Base
{
};
int main()
{
Base *ptr = new Derived;
std::cout << typeid(*ptr).name() << '\n';
}
Outputs "7Derived" (which is fine - the result of name() is implementation-defined, with no restrictions at all. (Though it is pretty much a given that it will be unique for the class.) See 18.5.1 in the C++ standard.
-
What do you mean would not be logical?
First, the name of a type as returned from name() is not something you will normally refer to, unless you have a very specific reason. Names are compiler dependent and sometimes rather cryptic. typeid(i), where i is a CBeing class object, on my compiler returns "6CBeing".
Second you are outputting it, not asking. The knowledge you have at the moment you write that std::cout statement is that you know the name of the derived class, whether you like it or not.
Anyways, if that is really so important to you, create a no-op virtual on base.
EDIT: And Corned Bee just reminded me of the obvious virtuality of the base destructor. Seems you didn't declare your destructor virtual.
-
You have a pointer to the base referring to a derived instance, you shoud have a virtual destructor anyway. Exceptions to this rule are extremely rare.
-
Well ok, but now that's even stranger than before, CornedBee, youre code
don't work properly for me... I use MSVC++ and then I get an error in file
"dbgheap.h" because of the "typeid(*ptr)" 's *.But then if I don't write the *
it prints the base class... :(
-
Tell us the exact error and show us the constructor and destructor for both the base and derived classes, please.
-
Did you get a warning about /GR-?
You have to turn on Run-time type information.
-
Don't know if it helps, but here is the error:
"Microsoft C++ exception: __non_rtti_object @ 0x0012fda4."
As I said, I just copied-pasted CornedBee's code directly in a new app,
and so I haven't modified anything... But is "rtti" something about an
old C standard?
-
No. RTTI is run-time type information, and it has to be turned on in order for this to work. You should be getting a compiler warning that warns you about this. Go to Project Settings, then switch to the C/C++ tab, go to C++ Language, and check Enable RTTI (or switch it to Yes). The steps are basically the same on all versions of VC++. When you do that and run that code it works fine in VC++ 6.0, 7.1 and 8.0.
-
Thanks! it was just because of "/GR". Now it works just fine!