Skip to content

N) Upcasting & Downcasting

kalinosia edited this page Mar 13, 2021 · 3 revisions

Upcasting​

​is used to convert​ instance, pointer or reference​ of child class type​ into instance, pointer or reference​ (accordingly)​ of base class type. This is always safe and can be performed implicitly.

Downcasting​

is used to convert​ pointer or reference​ of base class type​ into pointer or reference​ (accordingly)​ of child class type. This is often unsafe and must be performed explicitly.

static_cast vs dynamic_cast

void func(Base* ptr) {​
    Child* casted_ptr = static_cast<Child*>(ptr);​
    …​
}

User MUST ensure safety of such operation – no runtime checks!

void func(Base* ptr) {​
    Child* casted_ptr = dynamic_cast<Child*>(ptr);​
    if (casted_ptr) {​
        …​
    }​
}

Can be used to check if pointer of base type points to child class object of given type. Requires RTTI and polymorphic classes to work. It is always safe – if conversion is not possible, then nullptr is returned.

EXAMPLE

#include <iostream>

struct A {
    virtual ~A() = default;  // dynamic_cast can only work on polymorphic types
    std::string what;
};

class B : public A {};

class C {};

int main()
{
    B b;
    b.what = "foo"; 
    A* aptr = &b; //Chce mieć a z b (a<-b)-Rzu9towanie do góry OK
    B* bptr = dynamic_cast<B*>(aptr); //B z a (a->b) downcasting !!
    std::cout<<bptr<<"\n"; //addres lub nullptr
    if (bptr) {
        std::cout << bptr->what << std::endl;
    }
    if (!dynamic_cast<C*>(aptr)) {
        std::cout<<dynamic_cast<C*>(aptr)<<"\n"; //addres lub nullptr (0)
        std::cout << "not a C object" << std::endl;
    }
    return 0;
}

Clone this wiki locally