Most if not all OO languages have some way to determine whether an object belongs to a given class at runtime. In some languages -- both interpreted (like JS) and compiled (like Objective-C) -- classes are objects that exist at runtime, and an object can just be asked for its class (constructor and class respectively).

However, I'm curious what other strategies exist. For example, I don't believe C++ has class objects, so how does dynamic_cast work?

  • 2
    $\begingroup$ Here is a good talk from Cppcon about dynamic_cast implementation. $\endgroup$
    – chrysante
    May 22, 2023 at 22:19

1 Answer 1


Fat Pointers

A "fat pointer" is a pointer that stores additional data besides an address. For the purposes of dynamic dispatch and type checking, this data can be a pointer to a vtable which stores type information such as associated functions and a type ID. This approach is taken by Go and Rust, among others.

An example adapted from Rust's documentation:

use std::any::Any;
use std::mem::size_of;

pub fn print_if_string(s: &dyn Any) {
    // `&dyn Any` is a fat pointer, the size of two 'regular' pointers
    assert!(size_of::<&dyn Any>() == 2 * size_of::<&String>());

    println!("Object has type id `{:?}`", s.type_id());
    if let Some(string) = s.downcast_ref::<String>() {
        println!("It's a string({}): '{}'", string.len(), string);
    } else {
        println!("Not a string...");
  • $\begingroup$ What is the type ID in Rust? In Swift, as in ObjC, it’s a pointer to a type object. $\endgroup$
    – Bbrk24
    May 23, 2023 at 16:27
  • $\begingroup$ As an implementation detail, Rust's TypeId is currently a 64-bit integer which the compiler guarantees is unique for every type. $\endgroup$
    – Olive
    May 23, 2023 at 16:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .