Jump to content
  • Advertisement
Sign in to follow this  
noixtirdoe

dynamic_cast and static_cast

This topic is 5086 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Alright, so I learned a new trick... Using dynamic_cast to access child-class methods from a parent class and using static_cast to access parent-class methods from a child class.
class CParent
{
public:
    virtual void Init()
    {
        printf("CParent::Init()\n");
    }
};

class CChild : public CParent
{
public:
    virtual void Init()
    {
        printf("CChild::Init()\n");
    }
};

void use_dynamic_cast()
{
    CParent *pParent = new CParent;
    CChild *pChild = new CChild;
    pParent->Init();    // call CParent::Init()
    pChild->Init();     // call CChild::Init()
    pParent = dynamic_cast<CParent *> (pChild);
    pParent->Init();    // call CChild::Init() from pParent
}

void use_static_cast()
{
    CParent *pParent = new CParent;
    CChild *pChild = new CChild;
    pParent->Init();    // call CParent::Init()
    pChild->Init();     // call CChild::Init()
    pChild = static_cast<CChild *> (pParent);
    pChild->Init();     // call CParent::Init() from pChild
}


I was wondering, are there any other interesting things that can be done by using dynamic_cast and static_cast? -noix-

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by noixtirdoe
pParent = dynamic_cast<CParent *> (pChild);
pParent->Init(); // call CChild::Init() from pParent

That's kind of a waste of time. It's equivalent to: pChild->CParent::Init(); except that really, really braindead compilers might do the latter version more efficiently.

Share this post


Link to post
Share on other sites

void use_dynamic_cast()
{
CParent *pParent = new CParent;
CChild *pChild = new CChild;
pParent->Init(); // call CParent::Init()
pChild->Init(); // call CChild::Init()
pParent = dynamic_cast<CParent *> (pChild);
pParent->Init(); // call CChild::Init() from pParent
}




Output:
CParent::Init()
CChild::Init()
CChild::Init()


void use_dynamic_cast()
{
CParent *pParent = new CParent;
CChild *pChild = new CChild;
pParent->Init(); // call CParent::Init()
pChild->Init(); // call CChild::Init()
pChild->CParent::Init();
}




Output:
CParent::Init()
CChild::Init()
CParent::Init()

Your version doesnt achieve the same effect mine does.

-noix-

EDIT:
However, the use of static_cast to get a pointer back to the parent class is unneeded because then your trick of pChild->CParent::Init() works instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by noixtirdoe
*** Source Snippet Removed ***

Output:
CParent::Init()
CChild::Init()
CChild::Init()

-noix-


Well you don't need to use any cast to assign a child to a parent pointer/reference to achieve that, also 2 phase construction is bad thing what i mean by that is having a constructor that does half or no intialization then a init method to finish it.

Share this post


Link to post
Share on other sites
UH-OH!!

why you use classes and inheritance at all when you want to call functions that way.

Also what you do with your
pChild = static_cast<CChild *> (pParent);
is totally go around that little bit type security c++ brings to you.

only use static_cast if you KNOW 100% the object is the type you cast it to.

in your example of static cast i would expect behavior of the program will go insane if you define a second function to the CChild class. you MAY have luck and all goes like you want, but reordering the functions can already be the thing that brings your system out of balance...

Share this post


Link to post
Share on other sites
Here I added a print() function to the CChild class. After I cast a pointer to the parent class (which we already determined was not needed due to pChild->CParent::Init()), would you assume the pChild would try to call the parent class' method of print() only to find it doesnt exist? No, it actually calls CChild::print(). As far as I can tell, doing this doesnt make the program unstable because everything runs perfectly. But like everyone else has said, the call to static_cast isnt needed.


void use_static_cast()
{
CParent *pParent = new CParent;
CChild *pChild = new CChild;
pParent->Init(); // call CParent::Init()
pChild->Init(); // call CChild::Init()
pChild = static_cast<CChild *> (pParent);
pChild->Init(); // call CParent::Init() from pChild
//pChild->CParent::Init();
pChild->print();
}



Share this post


Link to post
Share on other sites
Quote:
Original post by noixtirdoe
As far as I can tell, doing this doesnt make the program unstable because everything runs perfectly. But like everyone else has said, the call to static_cast isnt needed.


You cannot assume that casting from a parent pointer to a child when calling child's methods doesn't make things unstable if you don't know what type of instance the parent pointer is refering to, it could be a sibling of "child" this all really depends on what member function does, any ways thats the whole point of using dynamic_cast to navigate type hierarchies that will give you an indication of navigation failure. static_cast just does blind cast so only use it when your absolutely sure of the type of the instance it refers to.

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid
Quote:
Original post by noixtirdoe
As far as I can tell, doing this doesnt make the program unstable because everything runs perfectly. But like everyone else has said, the call to static_cast isnt needed.


You cannot assume that casting from a parent pointer to a child when calling child's methods doesn't make things unstable if you don't know what type of instance the parent pointer is refering to, it could be a sibling of "child" this all really depends on what member function does, any ways thats the whole point of using dynamic_cast to navigate type hierarchies that will give you an indication of navigation failure.


Okay, that makes better sense, thanks :D

Share this post


Link to post
Share on other sites
There's a nice trick you can do but I can't remember, anyone like to help out.

Basically if you have:[cpp]class parent
{
...
};

class Child1 : public Parent
{
...
};

class Child2 : public Parent
{
...
};[/cpp]Then you have some way from a pointer to a Parent Object, of seeing if it's actually a Child1 object for example. We used macros in the class definition I think and then we'd use it to to the same thingfor every physics body unless it was a player car to alter the physics.

Share this post


Link to post
Share on other sites
pParent = dynamic_cast<CParent *> (pChild);

You don't need an explicit cast there. Just do

pParent = pChild;

The assignment is legal because the parent type only restricts what operations can be invoked on the object. I can't believe this hasn't been said yet.. And what resource is noixtirdoe using to learn C++ to not know this, yet already be learning about dynamic_cast..

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!