Help needed - Type Casting

Hi,

I am new to static_cast. Can somebody please explain me the output for below 2 cases :
case 1) in class A use void display() - output-> In B
case 2) in class A, use virtual display() - output-> In A

#include <iostream>
using namespace std;

class A{
public:
void display();
};
void A::display(){
cout<<"In A "<<endl;
}
class B:public A{
public:
void display();
int a;
};
void B::display(){
cout<<"In B "<<endl;
}
int main() {
A *objA = new A;
B *objB = static_cast<B*>(objA);
objB->display();
}
Please edit your OP to use code tags - it will make your code much easier to read.

Please use the format tag to format your code. It's pretty much unreadable otherwise.

Static cast means, "Please convert that thing to to something of this specified type using C++ conversion rules".

In this case, you're playing around with inheritance trees. Step back and look at this example. Let's forget about methods for now.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class C
{
public:
    long lvar;
};

class DI : base C
{
public:
    int ivar;
};

class DD : base C
{
public:
    double dvar; 
};


How do they look in memory?
* C occupies enough space to hold a long. let's say 8 bytes.
* DI needs to hold a long and an int, let's say 12 bytes.
* DD needs to hold a long and a double, let's say 16 bytes.

Let's look at some casts.
1
2
3
4
5
6
7
8
9
C *obj = new DI;    // create DI, (long + int) 12 bytes

DI *objdi = static_cast<DI*>(obj);  // objdi points to a DI, it is a DI so that's ok
objdi->ivar = 7;   // this is ok

DD* objdd = static_cast<DD*>(obj);  // objdd points to a DI, this is NOT ok, but
                                    // the compiler allows it
objdi->dvar = 7.3;   // this is wrong, the assignment overwrites the beyond the end
                     // of the object and corrupts the following 4 bytes. 


So, if you know the correct type being pointed to, you can do a static_cast to the derived class. If you get it wrong, there are no rules to stop you and you'll make a terrible mess.

There is a typesafe downcast, but it can only be used in object oriented programming. Specifically, classes that are used in C++ object orientation have virtual functions, and dynamic_cast can only be used by those.
Last edited on
Thanks @kbw for your quick response.
Actually I meant to ask from my question how we are getting output for case 1 as "In B" from my code snippet. Without creating class B object, how the display() method of class B is getting called ? .It should be "In A"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A{
public:
void display(); 
};
void A::display(){
cout<<"In A "<<endl;
}
class B:public A{
public:
void display();
int a;
};
void B::display(){
cout<<"In B "<<endl;
}
int main() {
A *objA = new A;
B *objB = static_cast<B*>(objA);
objB->display();
}


Last edited on
It's simple, B::display() is called because you called it.

objB is a B*, and you called objB->display().

It's only confusing because you may already know about virtual functions. But there's nothing virtual here, no types to be deduced at run time. It's all as you see it.

The root of the problem is that C++ supports multiple paradigms. And keywords like class mean slightly different things in different contexts. If not all about object oriented programming, so you need to learn about different behaviours in different circumstances and why it's so.
Last edited on
Ohh. I was expecting when we type case objA (referring to memory allocated to class A) to objB, then in this case objB should also be pointing to memory allocated to class A right . In this case output should be "In A" . Please rectify me if I am wrong.

Please explain the output of other case
case 2) in class A, use virtual display()
In this I am getting output-> In A . Confusing.

Thanks for your response
Ohh. I was expecting when we type case objA (referring to memory allocated to class A) to objB, then in this case objB should also be pointing to memory allocated to class A right . In this case output should be "In A" . Please rectify me if I am wrong.


What you have there is undefined behavior. You tell the compiler to treat your object of type A as if it were of type B when it is clearly not (although it may not be quite so clear to the compiler with the pointers thrown in.) Don't do that.



Is the output for both the cases is compiler dependent ?
The output is deterministic.
ngoyal1987 wrote:
Is the output for both the cases is compiler dependent ?

It is not compiler dependent. It is undefined. The fact that you have to use a cast for it should make you question what you're doing. You use casts to say "despite the compiler's objection to this, I know what I'm doing", which is clearly something you shouldn't be saying here.

1
2
3
4
5
6
7
8
9
class A {};
class B : public A {};

int main()
{
    A a ;
    B* b = &a ;   // This is disallowed by the compiler
    B* c = static_cast<B*>(&a) ;  // The compiler says no, but I say yes.
}


kbw wrote:
The output is deterministic.

I think you meant to say the function (A::display or B::Display) called is deterministic.

As the particular case presented invokes undefined behavior, the resulting output could be anything on a conforming implementation.
Thanks @cire and @kbw for your inputs.
Topic archived. No new replies allowed.