1

Consider below code:

#include <iostream>

using namespace std;

class Base{
    int i;
    public:
    virtual bool baseTrue() {return true;}
    Base(int i) {this->i=i;}
    int get_i() {return i;}
    };

class Derived : public Base{
    int j;
    public:
    Derived(int i,int j) : Base(i) {this->j=j;}
    int get_j() {return j;}
    };

int main()
{
    Base *bp;
    Derived *pd,DOb(5,10);

    bp = &DOb;

    //We are trying to cast base class pointer to derived class pointer
    cout << bp->get_i() << endl;
    cout << ((Derived *)bp)->get_j() << endl;**//HERE1**

    pd=dynamic_cast<Derived*> (bp); **//HERE2**
    // If base class is not polymorphic
    //throw error
    //error: cannot dynamic_cast `bp' (of type `class Base*') to
    //type `class Derived*' (source type is not polymorphic)

    cout << pd->get_j() << endl;**//HERE2**

    //Now we try to cast derived Class Pointer to base Class Pointer

    Base *pb;
    Derived *dp,Dbo(50,100);
    dp = &Dbo;


    cout << ((Base *)dp)->get_i() << endl;**//HERE3**
    //cout << ((Base *)dp)->get_j() << endl;
    //throws error Test.cpp:42: error: 'class Base' has no member named 'get_j'

    pb =  dynamic_cast<Base * > (dp); **//HERE4**
    cout << pb->get_i() << endl; **//HERE4**
    //cout << pb->get_j() << endl;
    //throws error Test.cpp:47: error: 'class Base' has no member named 'get_j'


    return 0;
    }

The Output

Gaurav@Gaurav-PC /cygdrive/d/Glaswegian/CPP/Test
$ ./Test
5
10
10
50
50

The way I am casting (Line HERE1 and HERE2 ) & (HERE3 & HERE4), what is the difference between the two ? Both produce the same output, So why to go for dynamic_cast

Gaurav K
  • 2,864
  • 9
  • 39
  • 68
  • probably see this post? http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast – taocp May 02 '13 at 13:03
  • You might find http://www.cplusplus.com/doc/tutorial/typecasting/ useful. It explains the different ways you cast in c++. – Kasper Munck May 02 '13 at 13:03
  • casts HERE3 and HERE4 are useless, the compiler can do them automatically: `bp = dp;` – BatchyX May 02 '13 at 13:05
  • @Muncken I have referred that tutorial. I am curious about just the difference between the type of casting used in my code – Gaurav K May 02 '13 at 13:06
  • @Gaurav great. If you hadn't already, it would have been a fine place to begin :) – Kasper Munck May 02 '13 at 13:07

1 Answers1

5

dynamic_cast is "safe" in that it either throws an exception or returns NULL when you are doing something "bad" (or, as Nawaz says, it doesn't compile, because the type is sufficiently bad that the compiler can see it going wrong)

The (Derived *)... form will act similar to reinterpret_cast<Derived *>(...), which is "unsafe" - it will simply convert one pointer to the other pointer type, whether that yields a meaningful result or not. It's your problem if that behaves "badly".

You can do this:

int x = 4711;

Derived *dp = (Derived *)x; 
cout << dp->get_j(); 

The compiler may moan a bit about the size of integer, but otherwise, it will compile the code. It most likely won't at all run, but if it does, the result is probably nothing "useful".

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Mats Petersson .. So you mean to say, it just typecasts (If it is of sort (Derived *)) without analyzing any consequence and the casting will always be true? – Gaurav K May 02 '13 at 13:08
  • 1
    *"dynamic_cast is "safe" in that it either throws an exception or returns NULL when you are doing something "bad"."*, **Or it doesn't compile to begin with**. – Nawaz May 02 '13 at 13:08
  • @GauravK: I amended my answer a little bit, and yes, I'm saying it will pretty much do whatever you ask it to do, whether that is "good" thing or not. – Mats Petersson May 02 '13 at 13:13
  • @MatsPetersson Got it `int x=450;dp = (Derived *) (&x); cout << dp->get_i();` compiled successfully and produced random result. This is C-Style of typecasting right ? – Gaurav K May 02 '13 at 13:17
  • Besides all those very strong arguments, Stroustrup makes a valid argument that it is very hard to see or search for C-style casts in code, whereas it is easy do do so with C++ casts. – juanchopanza May 02 '13 at 13:18
  • @GauravK: Yes, that is an example that has a slightly better chance of not immediately crashing, because at least the address of `x` itself is a valid address. But if `get_i()` was a virtual function, it would probably crash (but nothing is certain here - we are dealing with "undefined behaviour" and something other than what you expect is always a possibility in UB) – Mats Petersson May 02 '13 at 13:24