I have a factory method class that generates "Items" and returns a pointer to the Item that it creates.
I have derived classes of Item. For example, Item can be a "weapon" "consumable" or "armor."
I need to detect which type of Item is created so that I can properly cast the Item to that type. I did some test lines and it looks like it's doing what I want, except for adding a number associated with the type.
I had the line:
cout << "Type Created: " << typeid(pItem).name() << endl;
Which return the base class Item, but it would display: "4Item"
I then changed that to:
cout << "Type Created: " << typeid(*pItem).name() << endl;
Which would give me the correct derived type, but also throw in that number. So I get something like "5Armor"
Why did pItem return the base class? And why does it return an int with the type? How can I remove the int?
string type;
string returnedType = typeid(*pItem1).name();
for (int i=1; i < returnedType.length(); i++){
type.push_back(returnedType[i]);
}
cout << "type: " << type << endl;
Thanks
typeid
returns a const std::type_info&
. The std::type_info
type has a function called name
that returns an implementation-defined string representation of the name of the underlying type. There are absolutely no guarantees about what this function is going to return - it doesn't have to return a string that looks anything at all like the name of the type in the original program, and can decorate it however it would like to.
If you need to keep track of the name of the type that you created, I would suggest just adding in a virtual function like this one to your hierarchy:
virtual std::string getType() const = 0;
This function could return a nice, human-readable representation of the type that is guaranteed to behave in the way that you want (because you're responsible for writing it).
Hope this helps!
I use g++ and also had this problem. Now strictly answering your question without any intention to point what's the best approach, there is another way to deal with this case.
Here is a copy/paste example for you:
Create a type of yours, like MyType.h
#ifndef __MYTYPE_H__
#define __MYTYPE_H__
class MyType {
};
#endif
and a main.cpp file, like this:
#include <cxxabi.h>
#include <iostream>
#include <typeinfo>
#include "MyType.h"
template <typename T> char* get_typename(T& object)
{
return abi::__cxa_demangle(typeid(object).name(), 0, 0, 0);
}
int main(int argc, char ** argv)
{
MyType my_type;
std::cout << get_typename(my_type) << std::endl;
return 0;
}
This would output: MyType
I came to this solution based on an answer from this post that took me to this article.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With