hey what's up guys my name is Archana welcome back to another C++ video it's been ages since the last one gonna get back into it now though dynamic casting that's what we're gonna be talking about today you guys don't know what casting is in general in C++ I've got a video about that so definitely check that out and familiarize yourself with that before you move on to this video if you're not familiar with the type system in general I have a few videos about that as well because casting is to do with types casting is a way for us to convert between the types that we use in C++ so you need to make sure that you kind of understand how the type system works and more so maybe the point that the type system isn't something that is particularly enforced in C++ it's something that sales class kind of gives us as a way to protect our code but it's not something that we have to necessarily stick to or use because we can freely cast between types of any types like if we so choose but dynamic casting is provided to us as some somewhat of like a safety net really for when we want to do a specific type of casting now I've gone through kind of C++ style casts there's two kind of ways to cast there's a c-style cast which is just when you write your new type in brackets before a variable but then there's also the simplest I'll cast like static cast Const casts I'll make probably more videos about that but dynamic cast is a C++ style cast that only works in C++ doesn't work in C and it doesn't extra work to make sure that well like the way that we actually cast right it's some it's a it's actually a valid cast we don't just cast between two types and and whatever happens happens it's not like that it actually does some validation for us to ensure that cast is valid now whether or not you use dynamic cast is again totally up to you I want to give you some points to kind of I guess educate you to a sense of whether or not you should be using that if that's something you want to do but more so a dynamic cast is is quite a it's it's a tool that's more like a function it's important to realize that it's not just like a cast that is done at like compile time it's evaluated at runtime and because of that it does have an Associated runtime cost I might even make a video in the future comparing the performance of this normal kind of static cast versus that dynamic cast because of course since the dynamic cast does extra work it does kind of come with a small performance cost and that's normal but what dynamic cast does is specifically it's used for casts along the inheritance hierarchy now if you don't know what inheritance is in civil puzzle what classes are in C++ check out my video on inheritance and on classes and all that stuff because that will help you out but essentially what that means is if I have a class that is a subclass of another class and I want to either cast to the base type or from the base type to a derived type that's where I can actually use a dynamic cast right so let's just say we have an entity we have an empty class which is like the class for kind of all of our entities in our game and then we have like a player class and maybe like an enemy class and they're both entities so they derive from the entity class right if I just want to cast a player object back to an entity object that that's easy I mean a player already has the type entity so that that can be done implicitly no casting is necessary although if we wanted to we could still use dynamic casts to do it now the other way around is where things get a little bit more complicated so by the other way around I mean if we have an entity instance and we want to cast it to a player we have no way of knowing whether or it's a player right it's as far as we know it is an entity pointer right it's an entity instance is an instance of an entity object right so what is an entity object well it could be of type entity could just be an entity could be neither player right or enemy right could just be an MC but it also could be a player or it could be an enemy that's totally valid we might have made it a player we might have made it an enemy or it could be a thief it could be one of three types if we want to say that actually I'm gonna cost this two player we don't know if it is a player or not the compiler has to either believe us and if we're wrong let's just say it was an enemy and we try and access data that is unique to player or a function that modifies doubt of this unique two player our program will probably crash and it'll be like a disaster so because of that dynamic cost is actually used to validate that so what happens is if we have an entity instance that is actually an enemy right but we cast it we try and cast it to a player using dynamic cast that cast will fail and that dynamic cast will return a null pointer will just return zero and then we can validate that or do whatever we want so basically we could use it to check to see if an object is a given type so in other words I can try and do a dynamic cast on that entity object to convert it to player and then check to see if that returns not with it returns null that it's not a player right this is a lot of stuff is more easily explained encouraged so let's just dive in take a look at a basic kind of setup in which this might be useful and how we could actually use dynamic casting okay so what does a blank C++ project here because I really wanted to kind of show you guys everything so if we do what I just described if we have like an entity right if we have a player which is an MC so a public entity and then we'll also have that enemy class that I talked about which is also going to be an su right now in terms of the data that these will have if it's not even required for us to actually add any data so I probably wanted just to keep this brief I think because it's not really worth going into that stuff but basically the idea is we have three different types that they're probably filled with functions filled with data that is unique to their specific types how do I make an entity well let's just say I want to make a player I can just type in player player equals new player now for this video we're just gonna be using raw pointers I might make a video in the future about dynamic casting with smart pointers but this video just can't cover kind of the original dynamic cast that is used with the raw pointers so we have a player right now the thing is this player already has two types it has both entity and player associated with it it's actually even got like a type list thing as well which we might talk about later but it's got the those two types and T and player so what I could do is easily just change this to entity right oh I can make an entity II a people player right implicit cost however once I've done that if I want to go back to player I can't easily do that so I can type in player P equals E right that's gonna give me an error why because well I have to the different types the reason is that this could have easily been an enemy you know what if I do MC easy one or whatever equals new enemy all right what happens here what about what happens if I do a one right we don't it's still an entity but is it a player is it an enemy we don't really know at this at this point so because of that system we have to actually reassure the compiler by saying that hey it is a player now in this case there this is dangerous because E one's actually an enemy and so if we cast it to a player this will initially work and in fact if enemy has a function that like player also has or MC also has and we try and run that function it'll probably work we probably won't even notice any issues with it but if we try and do something that is unique to player that enemy doesn't have such as access certain data members that only player has a not enemy since the underlying type is actually enemy our program will likely crash or do some really weird things that we really don't want it to do so because of that we can again instead of using R or casts or even like a static class because you can still use you know a static cast with this like that I mean that's fine instead about what we can do is swap this out for a dynamic cast right now if we try to do that at this rate it's gonna tell us that it needs to have a polymer off the class site because dynamic cast only works with polymer for class types how do we do that well we basically need to have some kind of virtual function table that actually tell us that it is in fact a polymorphic class type so we can make this we need to say virtual void you know print name or something like this doesn't really matter but the point is that we'll make this class have a V table and thus there's stuff to override which means that is it's a polymorphic type and we can use dynamic casting with it again if this was a real entity class it would definitely have virtual functions so this is just making it a little bit more realistic as well so we can cast it right so we've got our e which is a player or we can use a one which is that and actually actually an enemy so we could say actually player just to make this a little bit more clear and then we could see it say actually enemy all right so if we try and get our our enemy into a player this would fail right but if we try and convert this player to a player that should work even though they're both at them at the moment they're both entities okay so let's take a look at what this code will do if we were to execute it I'll put a breakpoint here and hit f5 and of course you should make sure that my name is variables different things okay so this caste should fail right because this is actually an enemy and we're trying to cast it to a player so f10 and you can see this returns null the cast didn't work however if I try and do it here you can see that p1 is in fact a valid entity it successfully was able to cast it into a player because it actually was a player and that is essentially all the dynamic casters if the cast is valid then it returns the value that you want to play a pointer but if it is not valid because it's not the given type that you've kind of claimed that it is then it will just give you not that's what dynamic cast does in a nutshell now the question that you should have from this is but how does it know I haven't written anything and it's not like C++ or some managed language like C sharp or Java or anything like that how how does it know that player is actually a player like how does it know that this entity that I have is actually a player and not an enemy what the way that it does that is it actually stores runtime type information especially what it's called our TTI runtime type information it stores runtime type information about all of our types this does add an overhead but it lets you do things like dynamic casting so there's two things to consider here first of all our TTI adds overhead because suddenly types type types need to store more information about themselves than were otherwise present and big or to dynamic cast is also also takes time because we need to actually check to see does the type information match is this entity actually an enemy or is it a player what type is that we have to do that validation at runtime anytime we dynamic cost so because of that it does add that overhead now what we can actually do in our code here is turn runtime type information off if we don't need it so if we go to our properties and it's different favorite compiler but over here inside safe c++ and language and visual studio you can see we have this enable runtime type information if we were to switch that off and then we attempted to compile our code you would see that it actually would give us a warning which says dynamic class used on polymorphic type entity with this just means that we've switched off runtime type information so with that with our TTI off gives us unpredictable behavior and if we try and run this code and we hit f10 to get past this invalid dynamic cast you can see we actually get an access violation so that actually throws an error for us all right so it doesn't doesn't give us null because it can't because it doesn't have that type information so make sure that you are aware of the kind of implications the dynamic casts actually do because they do kind of do extra things and they do require that our TTI is on in most cases if we were to like for example do a cast from player to entity which is implicit anyway it would be fun it wouldn't crash but if we try and do something like this you can see it just just it just crashes doesn't even allow us to it at all and having our TTI on is pretty typical but also does add a bit of an overhead so just keep that in mind one last thing I want to show you is that because of dynamic because we have dynamic casts you know we can do that validation that I mentioned we can do something like if p0 now this is very similar to manage languages like C sharp or Java where we can basically try and check what is what something actually is so this actually enemy you know in like c-sharp we could do if if is if actually enemy is a player then we can do it all over in Java we have instance of so by using this kind of dynamic cast thing we can basically achieve the same thing we can say if dynamic cosplayer actually enemy right if actually enemy is a player instance then we can do the following code and if I just complete this you'll see that that's perfectly valid right but obviously we want to kind of cast it again and use it probably in that okay so therefore we'd probably do something like this this kind of code is pretty typical you see it all the time but just be aware that dynamic casting does incur a cost so if you're all about optimization if you try and write with really fast code you'll probably want to avoid that and I hope you guys enjoyed that video you can hit the like button you can also help support everything that I do on patreon for - the Cherno and I'll see you next time goodbye [Music]
Get free YouTube transcripts with timestamps, translation, and download options.
Transcript content is sourced from YouTube's auto-generated captions or AI transcription. All video content belongs to the original creators. Terms of Service · DMCA Contact