Upcasting and downcasting

Mar 2, 2023 at 1:13am
1
2
3
4
5
6
Derived d1; 
Base* BasePtr = &d1; 
Base& BaseRef = d1; 

Derived* d2 = new Derived 
Base* BasePtr2 = d2; 




During upcasting, Am I upcasting the derived class pointer/reference to base class pointer/reference to a derived class pointer/reference rather than upcasting to the type of object itself?

1
2
//For example
Base* BasePtr = &d1; 

(&d1 Upcasted from Derived* to Base*)

 
Base& BaseRef = d1; 

(d1 upcasted from Derived to Base&)

1
2
Derived* d2 = new Derived 
Base* BasePtr2 = d2; 

(d2 upcasted from Derived* to Base*)

d1 and d2 is being upcasted to a reference or pointer rather than the type of the object itself?


Not sure If i am right/wrong.

thanks for any help given.


Last edited on Mar 2, 2023 at 1:51am
Mar 2, 2023 at 1:55am
Yes, "upcasting" works through references or pointers. You're not upcasting "to the type of the object itself", if I'm understanding your question correctly.

The alternative would be copying, e.g.
1
2
Derived derived_obj;
Base base_obj = derived_obj;
and this is known as object splicing, which you do not want.
Last edited on Mar 2, 2023 at 1:55am
Mar 2, 2023 at 2:04am
@Ganado

yes, my question is you cannot cast an object or pointer of an object to another object but you can only cast it to the base class pointer/reference right?


I have another question, When I do upcasting I am not changing the original type of the object right? I just changing the way of how the program is treating the object because the object type is fixed at compile time and cannot be changed at runtime?

d1 is still a derived type object but I just changing the way the program is treating d1 when I upcast it from (Derived to base&).



Not sure If I am right?
thanks for help
Last edited on Mar 2, 2023 at 2:08am
Mar 2, 2023 at 2:10am

Base* BasePtr = &d1;
Base& BaseRef = d1;

no new object is being created during upcasting or downcasting
I am just creating a new pointer or new reference during upcasting/downcasting.
is my understanding correct?
Mar 2, 2023 at 2:13am
To use it polymorphically, yes, you can only cast it to the base class pointer/reference.

When I do upcasting I am not changing the original type of the object right?
Correct. You're not changing the original type of the object. You're just pointing to or referencing the actual object.

d1 is still a derived type object but I just changing the way the program is treating d1 when I upcast it from (Derived to base&).
You are understanding the concept correctly.

no new object is being created during upcasting or downcasting
I am just creating a new pointer or new reference during upcasting/downcasting.
is my understanding correct?
Correct. You can verify this by looking at the address of d1 and comparing it to BasePtr and the address of BaseRef.

Also, some code...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Example program
#include <iostream>

class Base {
public:
    virtual ~Base() {}
    virtual void foo()
    {
        std::cout << "Base::foo\n";   
    }
};

class Derived : public Base {
public:
    virtual void foo() override
    {
        std::cout << "Derived::foo\n";   
    }
};

int main()
{
    Derived derived_obj;
  
    Derived* p_derived_obj = &derived_obj;
    Base* p_base_obj = &derived_obj;
    
    Derived& ref_derived_obj = derived_obj;
    Base& ref_base_obj = derived_obj;

    Base sliced_base_obj = derived_obj; // bad!
    
    
    derived_obj.foo();     // Derived:foo
    
    p_derived_obj->foo();  // Derived::foo
    p_base_obj->foo();     // Derived::foo
    
    ref_derived_obj.foo(); // Derived::foo
    ref_base_obj.foo();    // Derived::foo
    
    sliced_base_obj.foo(); // Base::foo
    
    std::cout << '\n';
    std::cout << "&derived_obj:  " << &derived_obj << '\n';
    std::cout << "p_base_obj:    " << p_base_obj << '\n';
    std::cout << "&ref_base_obj: " << &ref_base_obj << '\n';    
}


Output: (addresses may vary between runs, but all three should be the same).
Derived::foo
Derived::foo
Derived::foo
Derived::foo
Derived::foo
Base::foo

&derived_obj:  0x505308
p_base_obj:    0x505308
&ref_base_obj: 0x505308
 
Normal program termination.
Last edited on Mar 2, 2023 at 5:46am
Mar 2, 2023 at 2:59am
Thank you for clarifying my doubts!
Topic archived. No new replies allowed.