Thread: typeid problem

  1. #1
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114

    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();

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    typeid(*Ptr).name()

    But that only works if Base contains at least one virtual function.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114
    Well, that's funny because I tried this too, and it still didn't worked...
    Can you show me something that actually works?

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    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.
    Last edited by Mario F.; 12-03-2006 at 03:45 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114
    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();

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    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.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    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.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    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.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114
    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...

  10. #10
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Tell us the exact error and show us the constructor and destructor for both the base and derived classes, please.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Did you get a warning about /GR-?

    You have to turn on Run-time type information.

  12. #12
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114
    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?

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    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.

  14. #14
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114
    Thanks! it was just because of "/GR". Now it works just fine!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 05:46 PM