Finding the Type of an Object in C++

Finding the type of an object in C++

dynamic_cast should do the trick

TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);

The dynamic_cast keyword casts a datum from one pointer or reference type to another, performing a runtime check to ensure the validity of the cast.

If you attempt to cast to pointer to a type that is not a type of actual object, the result of the cast will be NULL. If you attempt to cast to reference to a type that is not a type of actual object, the cast will throw a bad_cast exception.

Make sure there is at least one virtual function in Base class to make dynamic_cast work.

Wikipedia topic Run-time type information

RTTI is available only for classes that are polymorphic, which means
they have at least one virtual method. In practice, this is not a
limitation because base classes must have a virtual destructor to
allow objects of derived classes to perform proper cleanup if they are
deleted from a base pointer.

How do I check if a variable is of a certain type (compare two types) in C?

Getting the type of a variable is, as of now, possible in C11 with the _Generic generic selection. It works at compile-time.

The syntax is a bit like that for switch. Here's a sample (from this answer):

    #define typename(x) _Generic((x),                                                 \
_Bool: "_Bool", unsigned char: "unsigned char", \
char: "char", signed char: "signed char", \
short int: "short int", unsigned short int: "unsigned short int", \
int: "int", unsigned int: "unsigned int", \
long int: "long int", unsigned long int: "unsigned long int", \
long long int: "long long int", unsigned long long int: "unsigned long long int", \
float: "float", double: "double", \
long double: "long double", char *: "pointer to char", \
void *: "pointer to void", int *: "pointer to int", \
default: "other")

To actually use it for compile-time manual type checking, you can define an enum with all of the types you expect, something like this:

    enum t_typename {
TYPENAME_BOOL,
TYPENAME_UNSIGNED_CHAR,
TYPENAME_CHAR,
TYPENAME_SIGNED_CHAR,
TYPENAME_SHORT_INT,
TYPENAME_UNSIGNED_CHORT_INT,
TYPENAME_INT,
/* ... */
TYPENAME_POINTER_TO_INT,
TYPENAME_OTHER
};

And then use _Generic to match types to this enum:

    #define typename(x) _Generic((x),                                                       \
_Bool: TYPENAME_BOOL, unsigned char: TYPENAME_UNSIGNED_CHAR, \
char: TYPENAME_CHAR, signed char: TYPENAME_SIGNED_CHAR, \
short int: TYPENAME_SHORT_INT, unsigned short int: TYPENAME_UNSIGNED_SHORT_INT, \
int: TYPENAME_INT, \
/* ... */ \
int *: TYPENAME_POINTER_TO_INT, \
default: TYPENAME_OTHER)

How to find an object type in C#?

If there are only a few different types and you're taking a different action depending on the type then you can use is to check each type:

foreach(var thing in collection){
if(thing is TypeA){
doTypeA();
}else if(thing is TypeB){
doTypeB();
}

Another possible option, if it makes design sense and the objects are under your control, is to have them all implement an interface which includes a method to get an Enum describing the type? Then you can switch on that.

How do I get the type of an object in code?

That's not possible. A void * pointer, is just a pointer to the memory, nothing more, no more information is attached to it. It's impossible to do what you are asking, you can't know how many bytes to malloc.

That's why, the qsort function from stdlib.h library takes as a parameter
the size in bytes of each array element. If what you suggested was possible, then
qsort wouldn't need such a parameter.

Perhaps you could do something like this:

...
Foo *f;
f = Allocate(f, sizeof(Foo));
...

void *Allocate(void *item, size_t size)
{
return malloc(size);
}

Type Checking: typeof, GetType, or is?

All are different.

  • typeof takes a type name (which you specify at compile time).
  • GetType gets the runtime type of an instance.
  • is returns true if an instance is in the inheritance tree.

Example

class Animal { } 
class Dog : Animal { }

void PrintTypes(Animal a) {
Console.WriteLine(a.GetType() == typeof(Animal)); // false
Console.WriteLine(a is Animal); // true
Console.WriteLine(a.GetType() == typeof(Dog)); // true
Console.WriteLine(a is Dog); // true
}

Dog spot = new Dog();
PrintTypes(spot);

What about typeof(T)? Is it also resolved at compile time?

Yes. T is always what the type of the expression is. Remember, a generic method is basically a whole bunch of methods with the appropriate type. Example:

string Foo<T>(T parameter) { return typeof(T).Name; }

Animal probably_a_dog = new Dog();
Dog definitely_a_dog = new Dog();

Foo(probably_a_dog); // this calls Foo<Animal> and returns "Animal"
Foo<Animal>(probably_a_dog); // this is exactly the same as above
Foo<Dog>(probably_a_dog); // !!! This will not compile. The parameter expects a Dog, you cannot pass in an Animal.

Foo(definitely_a_dog); // this calls Foo<Dog> and returns "Dog"
Foo<Dog>(definitely_a_dog); // this is exactly the same as above.
Foo<Animal>(definitely_a_dog); // this calls Foo<Animal> and returns "Animal".
Foo((Animal)definitely_a_dog); // this does the same as above, returns "Animal"

Statement to determine the type of an object in C++

#include <boost/type_index.hpp>
#include <iostream>

int main() {
using boost::typeindex::type_id_with_cvr;
using std::cout;

int a = 42;
int& b = a;
int* c = &a;

cout << type_id_with_cvr<decltype(a)>().pretty_name() << '\n';
cout << type_id_with_cvr<decltype(b)>().pretty_name() << '\n';
cout << type_id_with_cvr<decltype(c)>().pretty_name() << '\n';
}

Output is:

int  
int&
int*

If I want to see the types, this is the method I use. It does require boost and some people don't like to see third-party libraries, but this does the job much better than C++'s typeid.

How do I check if an object's type is a particular subclass in C++?

You really shouldn't. If your program needs to know what class an object is, that usually indicates a design flaw. See if you can get the behavior you want using virtual functions. Also, more information about what you are trying to do would help.

I am assuming you have a situation like this:

class Base;
class A : public Base {...};
class B : public Base {...};

void foo(Base *p)
{
if(/* p is A */) /* do X */
else /* do Y */
}

If this is what you have, then try to do something like this:

class Base
{
virtual void bar() = 0;
};

class A : public Base
{
void bar() {/* do X */}
};

class B : public Base
{
void bar() {/* do Y */}
};

void foo(Base *p)
{
p->bar();
}

Edit: Since the debate about this answer still goes on after so many years, I thought I should throw in some references. If you have a pointer or reference to a base class, and your code needs to know the derived class of the object, then it violates Liskov substitution principle. Uncle Bob calls this an "anathema to Object Oriented Design".

How to determine actual object type at runtime in C++;

make sure the base class has at least one virtual method, include <typeinfo> and use your current code just with an additional dereferencing, typeid(*b).name().


in passing, note that a typeid call is the one place in C++ where you can dereference a nullpointer with well-defined behavior, which implies that it can throw an exception:

C++11 §5.2.8/2:

“If the glvalue expression is obtained by applying the unary * operator to a
pointer and the pointer is a null pointer value (4.10), the typeid expression throws the std::bad_typeid exception (18.7.3).”

Can I determine the object type in Object-C?

You have to check each object and only add its value if is is of obj1 class.

int total = 0;
for (obj1 *t in arry1) {
if ([t class] == [obj1 class])
total += t.value;
}

Please note that it common to start class names with a capital letter. Also Obj1 would be a misleading name as it implies instance, not class.



Related Topics



Leave a reply



Submit