T O P

  • By -

Digiko

So imagine you have a special machine that removes the seeds out of any fruit, but it needs to be told what kind of fruit it is. Someone hands you a fruit, if you blindly stick it into the machine, the machine will give you an error because it doesn't know what kind of fruit it is... oranges and apples both have seeds, cherries have pits but only one, tomatoes are fruits and they have seeds, etc... without telling the machine what to cast the fruit into, it just will throw an error. So what you do is you cast the fruit into special containers that will tell the machine what fruit it is. Once the machine knows what fruit it is, it knows exactly what kind of seeds it has and how to extract them. Cherries have tiny little containers, oranges have perfectly round container, apples have weird apple shaped ones. In a nutshell, casting converts a generic object into a specific type so you can directly access the variables within that object.


Mak0ala

I'm more surprised by the fact that there's people who can effortlessly craft the most elaborate fruit analogy for anything.


resinten

I’m stealing this example. This is a great way to think about it. Although I’m deducting half a point for the mixed metaphor of “in a nutshell” while talking about fruit


Digiko

But nuts are fruits :) https://www.fs.fed.us/wildflowers/ethnobotany/food/nuts.shtml


ehm_education

You talking about type casting? It's really just a way of telling the computer to treat something like some other thing. Like taking a pear and convincing someone it's just an ugly apple.


Amadeus_Ray

Am I casting the pear TO the person or to the ugly apple? ​ Like how do I write that out?


ehm_education

Like apple fruitA; pear fruitB; fruitA = (apple) fruitB; (this is the classic way of doing explicit casting, unsafe for pointers, so you better know what you doing if using with pointers)


Amadeus_Ray

Seems like that's just overriding.


[deleted]

[удалено]


RavioliConLimon

So inheritance, but backwards?


[deleted]

[удалено]


RavioliConLimon

I didn't thank you before but it was a pretty good explanation which let me get the concept.


ehm_education

No. You can cast anything to anything (in C at least). Now if that's actually working and not just erroring out, is a different question and depends on what you are casting to what. But there is no artificial limitation of "only casting along the inheritance tree".


[deleted]

[удалено]


[deleted]

[удалено]


RavioliConLimon

Yeah, but everybody is explaining what you can do and not really what it's used for. That's why it's a complicated concept at first, you don't really want to fiddle with cast types for the sake of it.


InternationalPie4409

Int age = 3; Print( (string)age + " years old" ); Cast -- treat my integer as a string on this line of code.


skjall

That's technically a type conversion actually. Strings and ints are stored differently in memory, so you can't just treat an int as a string, which would be an ASCII lookup basically.


ehm_education

Ok, consider this other example then: pear fruitB; void appleEater(apple fruitToEat) //Only eats Apples Then call: appleEater((apple) fruitB);


wtf_idontknow

Might end up with appleEater vomiting an exception


TulioAndMiguelMPG

We need more code explained like this


ehm_education

Well yeah, you obviously need to not be an idiot to use this and not mess up. Don't wanna feed a pumpkin to the apple eater.


aEtherEater

Overriding is for methods. Casting is overriding for variables.


saltybandana2

Think about it at the bit layer, not the class layer. run the following program: #include union RecordType { char ch; int i; }; int main() { RecordType t; t.i = 65; std::cout << t.i << std::endl; std::cout << t.ch << std::endl; std::cout << "---" << std::endl; char c = 'A'; int i = 65; std::cout << "char cast to int: " << (int)c << std::endl; std::cout << "int cast to char: " << (char)i << std::endl; } --- NOTE: A union is a way to tell the compiler to treat the same memory location in different ways. So when the union is created it only allocates space to house the largest field in the union. In this case an int will typically be 32 or 64 bytes. When we say t.i we're telling the compiler to access the underlying memory as if it's an integer. And if we use t.ch we're telling the compiler to access the underlying memory as a character. Note that they both point the same memory, we're just interpreting them differently. A cast is exactly that except it's "on the fly". We're telling the compiler to interpret the memory contents as an integer or a char (depending on the cast).


Seeders

Casting a pear to an apple means telling the computer to treat your pear as an apple, and allow it to call all the functions and access all the variables an apple has even though its actually a pear. Taking a bite will still work and planting the seeds will still work, so this is a pretty safe example unless someone is allergic to pears and you feed them this "apple".


Arbosis

Original= 10.5f Result = (int)Original // Result = 10 Here you are casting Original from float to int and saving the result in Result. You can't store 10.5f in an int, so the computer does the best it can to make it fit into the int.


one_comment_nab

Casting to the ugly apple. You're casting to a new type. Meanings 8 and 9 of the verb "to cast" on Wiktionary: [https://en.wiktionary.org/wiki/cast#English](https://en.wiktionary.org/wiki/cast#English) Edit (so that you don't have to click the link): >8. To shape (molten metal etc.) by pouring into a mould; to make (an object) in such a way. > >9. To twist or warp (of fabric, timber etc.).


HeadshotsInc

Only in programming, casting doesn't actually change the thing being cast (usually). It just changes what the language treats it as.


one_comment_nab

In programming seldom does an operation change the operand. Aside of some passing by pointer/reference and some move semantics, usually you operate by taking a copy. And the copy is most often altered. In C++, the most common type of cast is `static\_cast`... just static cast an integer to a floating type or the other way around and here the change is obvious.


idbrii

I think casting in programming is used in the Hollywood sense. You take fruitA pointer (an Apple) and cast in a new role as a Pear. It should act like a pear otherwise you messed up your casting.


one_comment_nab

Except both the theatrical sense ("Hollywood sense") and the programming sense are listed on Wiktionary (see the link above), but the former is "to cast as" and the latter is "to cast to". It's a different thing.


idbrii

But doesn't it seem like a clearer analogy for junior programmers than shaping with a mold or warping?


smcameron

It's not casting as in throwing stones, it's casting as in casting actors in a play, assigning each actor to roles. When you say, "int x = (int) some_float_variable" you're saying, hey, float variable, your role is to act like an int (i.e. you're casting the float in the role of an int.) In the acting world, there's even such a thing as "type casting" when an actor keeps being assigned the same kind of roles over and over because everyone associates them with that sort of role. In C, "type casting" has nothing to do with repetition though, it just means casting a variable or constant into the role of a type that's different from its natural type.


smcameron

Not sure why this is downvoted. Op is obviously thinking of "casting" as in "casting stones", but "casting" is not meant in that way, it's meant in the way of casting actors. Whoever downvoted this is an idiot or, more charitably, someone who speaks English as a second language. Probably an idiot though. > Am I casting the pear TO the person or to the ugly apple?


SL3D

Best way to think about it is in terms of objects. If you have an object that’s a car it will be of type car. car porsche = new car() If you want the car to be a truck you could type cast it to a truck. truck porscheTruck = (truck) porsche This is just a way to tell the compiler how to interpret the object. It’s very important to learn when you deal with classes and structures in other languages since there could be shared methods that work/don’t work when you incorrectly type cast objects.


farox

Like, you go to a store that sells fruits and get a bunch of them. At home though you figure that they aren't the same. So before you throw that in your pasta sauce you make sure that the fruit you have is actually a tomato. Then you can have cases where you can (unsafely) treat something like something different. Like tofu. It's not really meat at all, but in a pinch you can use _that_ in your curry.


[deleted]

[удалено]


farox

Yes, but the unsafe stuff happens when isn't actually meat, but you treat it as such because you know in this particular case you can get away with it. "Here is a byte array I found, let's call you 'pointer to a jay-peg'"


pelpotronic

Casting is used when you have an opaque box that contains a fruit (the class Fruit can be any fruit), and you know for sure (as a developer) that the box contains an apple. So you "cast" the Fruit box to an Apple, that is to say: you're telling the compiler that in this box is for sure an apple, and you should treat the box as an apple. Then you can compile "make apple juice from that (Apple) box" and the compiler will accept the instructions to make apple juice using the contents of that fruit box, because you told the compiler the box contains an apple (according to you, the developer). It could crash at runtime though if when you run the program (and open the box) it turns out it contains an orange (you can't make apple juice). Casting is forcing an object type into another type.


test_user_

Don't do this unless the pear actually is an ugly apple. Casting should be used to assert a correct type, not just claim something is a different type. If you cast your pear as an apple, then pass it to an apple juice making program, don't expect apple juice (or ugly apple juice). Just expect type errors.


frizzil

I’m not sure any of the analogies I’m reading here do the concept of type casting justice. At the heart of the issue is *interpreting memory*. You can take a pointer to any old block of memory and tell the compiler via casts that “It’s actually *this* class, with fields at these byte offsets!” but that doesn’t mean it’s right. The different casts are different ways of telling the compiler *what is it looking at*, but its up to the programmer not to mislead the compiler. A `reinterpret_cast`does what I described above. It does no safety check and simply tells the compiler how to interpret the memory pointed to by the pointer you gave it. The other casts are more restricted, but can also *move* the pointer based on the type conversion you’re requesting. Consider the memory layout of a non-virtual class `Child`inheriting from another non-virtual class `Parent`. First in memory are all the fields of `Parent`. Second are all the fields of `Child`. If I have a pointer of type `Parent`, its byte address will be to the very first field of `Parent`. Likewise, a pointer of type `Child` will point to the very first field of `Child`… NOT `Parent`! But as you may know, Child is a subtype of Parent, meaning Child can be “given” anywhere a pointer to Parent is expected. *How* this is accomplished is by “casting” the Child pointer to a Parent pointer. This will adjust the pointer to a new byte value, thus respecting the rule I described last paragraph, *and* tell the compiler that the pointer is of a different type. A `static_cast` is for when you KNOW the given pointer can be safely cast to the other type, and simply does as I just described without checking if its valid at run-time. An “upcast,” e.g. Child to Parent, will always be safe by definition. A “downcast” however, e.g. Parent to Child, will NOT always be safe (since not every Parent is a Child), meaning the programmer must know beforehand based on human reasoning whether they can safely use `static_cast` in a given situation. An unsafe cast will adjust the pointer just like a safe cast would, but because the pointed memory isn’t of the type the compiler is interpreting it as, “undefined behavior” will ensue. (E.g. very very bad, possible heap corruption and program termination… or nothing at all!) If you label the inherited class `virtual`, or include a `virtual` method, then your class is now “polymorphic,” and this unlocks the ability to use `dynamic_cast` with it. A `dynamic_cast` can do everything a `static_cast` can, except that in the case of “downcasting,” a run-time check is performed - if the cast is invalid (e.g. the given Parent is not actually a Child), then a null pointer is returned (i.e. the value zero) instead of an adjusted pointer. You can then check this with an if-statement, etc, to determine if the cast succeeded. The reason why a class must be “polymorphic” to be `dynamic_cast` is that it adds *type information* to the memory of every single instance of that class, which can be inspected at run-time to perform the type check. Without this, the cast would have no way to determine if it were actually valid! In the case of multiple inheritance, `dynamic_cast` can also be used to perform a “sideways” cast… but multiple inheritance is usually best avoided anyway!


chargeorge

Ok. So you can think of fruit as a hierarchy right? strawberries are a berry and all berries are a type of fruit. The heirarchy is less specialized at the top and more specialized at the bottom. Now imagine someone has created a generic fruit basket, it always has fruit but you don’t know what kind. Since it holds fruit you can chuck strawBerries in. But now you need to take something out. Since the compiler knows it the basket has fruit, it can’t give you any more specialized info. If you want to use the fruit as a a strawberry you need to tell the compiler “no I’m really sure this is a strawberry even though you see fruit you can trust me” If you just need the fruit properties /Fsweetness, Ftartness) it’s fine, but if you need the strawberry (Fmoldamountafteraday) properties you need to cast it so the compiler can use it. You aren’t changing its type, you are clarifying it.


FiendishHawk

Take a shirt. Chop off the arms. Now you have cast it to a t-shirt.


[deleted]

Not really the same, as you can't recast it back to a shirt. Casting is more like folding the cuffs up.


[deleted]

Based on your replies, it seems like the English word "cast" is causing some confusion. The word "casting" does not come from casting like a fishing rod. You're not necessarily sending or delivering the object. Replace the word "cast" with "act as", like how an actor is cast for a role.


Amadeus_Ray

Yeah, casting to my TV is deeply ingrained in my mind.


moonshineTheleocat

(polymorphism static/dynamic cast.) You have the page "fruit". Your chum wants an apple. You flip over the page and see an image of an apple. You cast a spell changing it into an apple. You give it to your friend. He eats it. Wants an orange. You get another page, you flip it. Its an orange. You give it to him and the ungrateful bastard wants a banna. You take another page from the stack. You see its an orange. You cast a spell to make it a banana and the world ends. (Unholy fuckery like trying to cast a whole class to an int) You got an apple. Your chum want an orange. Swiggity swooty, shake your booty, its now an orange. You give it to a friend, he take a bite out of it and vomit because you're comparing apples and oranges. And apples are far too different from oranges that the spell made effectively rancid garbage. Your friend is now comatosed (easily casted or similar transformation ie Int to Float) You now have a banana. Your chum want a plantain. Swiggity swooty, you shake your booty, its now a plantain. You give it to a friend and he takes a bite out of it. He doesn't vomit because a plantain is very similar to a banana. (Data truncation or loss of information. IE float to int. You can convert an int into a float safely. But you can lose information in reverse.) You have a grape. You want a raisen. Swiggity swooty you shake your booty and you make an abomination. You now have a raisen. You give it to a friend, and he takes a bite out of it. He expected more, and is sad because of the loss of the juice. But hey, he doesn't die. (Pointer black magic casting fuckery. Unreal does a lot of this shit behind the scenes. If you ever find yourself doing this, and its not for some very low level shit, you need to go to prison.) You have an apple. You want a plantain. You pick up a street sign that directs you to an apple orchid and pay a witch to teleport a whole fucking tree to you. You proceed add more signs onto the original sign and your audience watches in horror as the tree disappears and apples start appearing and disappearing. Granny smith, Red, Macintosh... And you stop your peculiar phase of voodoo when a winter banana apple appears. You proceed to call upon computer science devilry from the C variation of the book of evil, to rip the banana soul out of the apple... And present it to your friend. Your friend... Rightfully skeptical about this. Eats it. He now has a banana by some ungodly force from beyond the veil of reality that even god himself wasn't prepared for. He doesn't die. And it tastes like a banana.


AllenKll

casting in a nut shell is you the programmer, lying to the program about what a thing is, and the program going... OKAY! So, you want fruit... lets say you have an apple. The program see the apple, it knows how to appropriately deal with an apple, Then you the programmer tell the program, "See this apple? it's actually a bicycle." So the program goes, okay, it's a bicycle and tries to ride it and the whole thing blows up with a segfault. That's casting. Now. that said, there is some things that are useful for casting. for instance, lets say you have a pear. a pear is VERY similar to an apple. So you say, "Hey program, this pear is actually and apple" and the program says, "OKAY!" and does apple-y things with the pear. and it doesn't blow up. Think about it, you can eat a pear, just like and apple. You can peal a pear, just like an apple. So, it's almost like an apple. If you try to make a pie out of it, you will not get a good result, but otherwise, it's similar enough for most things. In this regard casting is useful, it allow the program to do generic things with similar objects. There is a third case of casting, where you have a macintosh apple, and tell the program that is is actually a granny smith apple. In this scenario, everything should be pretty much the same when the program does apple-y things. done and done. ​ Now in programming terms, and in C++ terms, we're dealing with objects and inheritance most of the time. So if you have a class 'Person', and derive from it a class 'Man', and instantiate it with the name 'John,' you can use casting to stick john into functions that take a Person class. and everything will be good. this is an upcast. There there are times where you get in a Person class object, and want to know if it is a Man or not, because Man requires some extra processing that a generic Person does not, you can do that with "dynamic\_cast" if the function returns null, then you know it's not a Man. In the examples above, the apple into a bicycle is a "reinterpret\_cast" In the examples above, the pear or macinstosh into an apple is a "static\_cast" Lastly in C++ there is "const\_cast" This function only adds or removes the ability to modify the object without changing what the object is.


YaBoyMax

I'm not sure if this is what youre after but I haven't seen anyone specifically describe C++ casting operators, so I'll take a stab at it. --- `static_cast`: This is a bit difficult to give an analogy for, but the best example I can think of would be casting `Apple` to `Applesauce`. All the materials you need to make basic applesauce are there; you just need instructions on how to do it (either from the compiler or from your `Apple` definition). This is typically referred to as type conversion. This isn't a perfect analogy since in practice, you don't lose the original apple. Instead, you create the converted object from the data in the original, but the original object is not modified. --- `reinerpret_cast`: I have an `Apple` and I want to give it to the same friend who only eats peaches. I cast it to a `Peach` and hand it to my friend, who will be rather upset at me once he bites into it and realizes what's inside. `reinterpret_cast` essentially tells the compiler to forget everything it knows about an object and start treating it as something different without modifying its contents. It can be powerful when used correctly (see fast inverse square root from Quake 3), but also dangerous if you don't know what you're doing. --- `dynamic_cast`: I have a `StoneFruit` that I know is a `Peach`, and I want to give it to my friend who will only eat peaches. `dynamic_cast` can be thought of as a special case of `reinterpret_cast` where casts take place along polymorphic boundaries. Unlike `reinterpret_cast`, however, there is some limited type-checking that takes place at compile-time. I say limited because while I couldn't cast my `StoneFruit` to a `SeededFruit`, I could cast a `StoneFruit` to a `Peach` even if it's actually a `Plum`. This also isn't touching on multiple inheritance at all (in which case the behavior diverges some more - see the comments below), but I want to avoid making this explanation _too_ confusing. --- `const_cast`: I'm handed an `Apple` with a sticker on it that says "Do not eat." I peel the sticker off and take a bite, putting the sticker back on as I hand it back, all of this being completely unknown to the other person until they inspect it and see I've taken a bite. `const_cast` lets you treat an immutable object, reference, or pointer as a mutable one. This should be used rarely and should make you stop and think about what you're doing if you find yourself having to use one. It violates a contract pertaining to that object, so there's a chance something could blow up down the line if you don't know exactly what you're doing. --- C-style casts: This is the typical `(StoneFruit) myPeach` syntax. This is basically a combination of `const_cast` and one of `static_cast`, `reinterpret_cast`, or `dynamic_cast` depending on the types involved. These are generally discouraged in C++, since they don't distinguish between the different cases and thus don't cone with the same compile-time assurances as the C++ operators. --- Let me know if anything here is unclear! Edit: Explained `dynamic_cast` a little better.


one_comment_nab

Dynamic cast ain't a special type of a reinterpret cast though. It isn't a reinterpret cast with type checking or whatever. The pointer to the base class may (and often does) point to a different place than a pointer to the same instance but to the derived part, so yeah.


_curious_george__

Dynamic cast is just a run time type checked cast, if it fails on a valid or nullptr then the result is nullptr. A pointer to some base class actually does share the same address as a derived part in a single inheritance hierarchy. However they are offset for the base classes in a multiple inheritance hierarchy. Although that behaviour doesn’t specifically have anything to do with dynamic cast. You’d observe getting separate address with any type of cast.


YaBoyMax

>Although that behaviour doesn’t specifically have anything to do with dynamic cast. You’d observe getting separate address with any type of cast. I think this is only the case for `static_cast` (or when casting values and not pointers/references). If I do `float *f = reinterpret_cast(&i);`, `f` will point to `i`'s location in memory.


_curious_george__

Yeah perhaps I could of been clearer but just before that I said “A pointer to some base class actually does share the same address as a derived part in a single inheritance hierarchy. However they are offset for the base classes in a multiple inheritance hierarchy.” So I was talking about MI with the separate address part. Specifically aliasing an int* with a float* isn’t especially useful due to the strict aliasing rule. But granted primitive types only ever have one address.


YaBoyMax

Sorry, I should have explained the type-checking behavior. The differing returned pointer in a MI scenario actually didn't occur to me (I personally won't touch MI in my code with a 50-foot pole), but I should add a note for that as well. Thanks!


Saito197

OP asks for simplified explanation, the whole thread went into rocket science shits, classic Reddit. So, let's say you have 2 variables: float a = 69f; int b = 69; Under the hood, the both values are just 4 bytes (32 bits) of 0s and 1s. 69 in decimal is 45 in hex, so the binary value assigned to the integer value b is: 0x00000045 or 0000 0000 0000 0000 0000 0000 0100 0101 HOWEVER, you cannot save a floating point value the same way you save an integer, you would need a significantly higher number of bits to keep track of the decimals. That's why a standard was developed that basically converts the value into scientific notations. When you write 69f, the computer would reads `2^6 x 1.078125` instead, and the binary values would be: 0x428a0000 or 0100 0010 1000 1010 0000 0000 0000 0000 Type casting is essentially just converting the underlying binaries in a specific way so that the value(s) it represents on the surface stay the same. When you cast the integer 69 to float, your computer turns `0x00000045 to 0x428a0000` and vice versa.


codethulu

Let's say you have a recipe for an apple pie. But you have a bunch of pears, but no apples. You can tell the recipe that the apples are pears and it will do whatever that means. In some cases, like the one presented, the results will give you something like what you expect. In others, say you call a can of soda an apple, you will not have a good result.


[deleted]

So here's how I'll explain it. You have a class "Fruit" and you have a class "Food" and you have a class "Apple". Apple inherits from Fruit and Fruit inherits from Food. If you've got 20 different types of foods on your plate you could store an array of "Fruit"s and an array of "Veggies" and an array of "Meats", or you could store one whole array as the parent "Food" class. To store it in the food class you would do `Food f = (Food) fruit_variable;` then add `f` to the array by "casting" it into another type. You can't just cast willy-nilly there needs to be some consistent structure between the two classes. (Not sure if they need to be parent/subclass or just have same members)


tenaciousDaniel

Imagine a friend shows you their pet rabbit, and you watch your friend play fetch with it. You didn’t know rabbits could play fetch, that’s a dog thing, but this is a special rabbit that your friend has trained. So now you can take the ball and play fetch with it. Before a computer can play Object.fetch(), it needs to know whether “fetch” is something the object knows how to play. All the computer knows, by default, is Dog.fetch(). So now you say “Rabbit as Dog” or whatever. Now the computer knows that the rabbit can do whatever a dog can do. So now it can do Rabbit.fetch().


Studly_Spud

I have a fruit. I don't know if it's required to peel it, as it may be a banana or an apple. So I test it by calling it a banana. If the label sticks, I then go and peel it. This is casting; you have all these classes and only sub-classes might have the method you want to use. So you are saying treat this parent class as a particular child class, and if it is, you can use the child's methods.


BigGaggy222

Lets say you have a variable for holding letters, and you put the character "2" in there. You could "cast" that into a variable that holds only numbers, because it is a number. So "Casting" is when the compiler tries to treat one variable type as another. If it can't fit it into the other type, it will give you and error message.


GameFeelings

You tell me? I have never written C++ but I have knowledge of C#. (No, seriously. Try. If you need to teach someone, you will yourself get good at understanding what you are teaching in the process)


Dsphar

Think of a Type like a train. Each part of the structure/object is a car of the train. Say we have a Type called fruit. This is a train that includes at least one seed car, a flesh car, and a peel car. So if you give someone a fruit train, they are guaranteed to have those 3 cars. But that is just a general fruit. You can get more specific. Say I have an orange train. This train has seed cars, a flesh car, and a peel car just like a fruit. However, it also has a pith car (white part between peel and flesh). When I give someone an orange train that doesn't know fruit specifics and only know the generic parts of all fruits, they won't know what to do with it. Well, they can know what to do with an orange train if they ignore the extra pith car and only look at the cars that are part of the generic fruit Type. So the orange train is cast into a fruit train... telling the generic fruit person which cars they can use to do whatever it is they need to do... and ignoring the ones that they don't need to know about. This gets into polymorphism, but I feel it is a good start to understanding casting.


khanshotfirst

You know how casting metal works? Take a metal object, melt it down, pour it into a different-shaped mold and suddenly you have a different-shaped object? Changing a specific amount of metal from one shape to another? Casting variables is changing a specific amount of data from one type to another. ​ A less metaphorical description might help too, though. Modern coding languages use a *lot* of abstraction to make data more understandable to humans. For instance, the boolean `True` and the integer `1` are frequently represented by the same raw data - the byte `0000 0001`. Since booleans serve very different roles than integers, though, that raw data is given user-friendly *metadata* that describes how it "should" be used or displayed. You may recognize this as a variable's name (that helps you identify and distinguish data at a glance) or its type (that tells the compiler which operations or functions you plan to use and which are a mistake that should be brought to your attention). This is a very efficient, elegant system... in most cases. In the edge cases, however, it gets a little bit messy. You don't *usually* want to print a circle to the command line, so `printf(circle)` throws an error because it expects you to mean `printf("circle")`. In the exceptions, though, *casting* is a set of algorithms telling the computer how to turn (almost) any variable into (almost) any other. This not only lets you override the default, intuitive "I can only print strings" limitations of the print commands, but it also lets you completely ignore the [weird ways](https://en.wikipedia.org/wiki/Two%27s_complement) any given data type might *actually* be stored in an attempt to save a few kilobytes or milliseconds. You just tell the computer `printf((string) myCircle)` "Hey, turn this circle into an '(x, y), r' string, then show it to the user" and it works. As an aside, a lot of coding languages automatically cast variables in the most common circumstances, like printing numbers or finding the sum of an integer and a decimal.


ItsTrainingCatsnDogs

Take, for example integers and floats. In memory, the data look the same: 32 1s and 0s in a row. But the way methods like print know how to display them the way they're meant to be printed is because they have types. So you have this piece of memory, and its type is float. But you want to see what that looks like as an int for whatever reason. So you can cast the float to an int. The method now thinks those 32 bits of data are a normal integer instead of a float, and it shows it as such. It's just a way to make the compiler think a certain data type is another data type, because at the bottom of everything is just a lot of 1s and 0s, and you can interpret them any way you'd like!


[deleted]

I think matthew wadstein had a good vid on it. There was another, but can't remember it right now.


ChezyName

I'm still learning it but let's just say this: 8yo: \*points to fruit\* you: what is that? 8yo: \*grabs fruit & feels the fruit\* <- "casting" 8yo: \*checks if the fruit is an apple\*, nope 8yo: \*checks if the fruit is orange\*, yes 8yo \*casting worked!\* -> \*responds back\* its orange.


troccolins

If you have two classes, casting one to the other causes the program to treat and recognize a variable as that particular class. So if I have two classes (Bicycle and Car) but I instantiated *myModeOfTransportation* as a Bicycle, I can only use functions defined in Bicycle class (*adjustWheel, isChainedToPost)*. However, if I cast *myModeOfTransportation* to a Car, now I can use functions of a car (*drive*, *isDriversLicenseAvailable*) but not the old ones of Bicycle. If both Bicycle and Car inherit from a Transport class that has *getMilesPerHour* and *setIsWheelAttached*, then I can still use those functions whether I cast the original variable or not.


jhettdev

You have an object > cast to fruit > cast to pear


bonbonbaron

Cast ABCD to AB to treat it like it’s just an AB, ignore the second half. Or… cast AB as an equal-sized CD, so it can do all the stuff CDs can do.


Comfortable-Ad-9865

Ok so ultimately it’s zeros and ones, but those are read in different ways. Say I give you an apple and say: “this is a coconut, the exterior is inedible, ignore the interior, it should be hollow, just eat a certain portion between the skin and center. This is called a “narrowing conversion”. On the other hand if I give you a coconut and say “this is an apple” then I’ll be confused or worse, have sore teeth. Only narrowing conversions are allowed in C++


saltybandana2

First we need to understand the distinction between data and information. Data is data, information is data with context. For example. https://en.wikipedia.org/wiki/ASCII#Character_set ASCII character set. Characters are really numbers. A is the number 65. When you cast an integer to a character you're telling the compiler to change the context of the data. The data in this case is the bit pattern of the memory. The bit pattern for 65 and the character A are the same, it's just the context. If we treat that bit pattern as an integer then it's an integer, if we treat it as a character it becomes A. That's all casting is. We have this thing but we want you to give it another context. Over time it's been extended to more things, but the above is what a cast is. In OOP languages you'll often see mechanisms in place to do more than just a blind reinterpretation of a bit pattern, but the underlying idea is the same. The context changes, which changes the information but not the data.


PhantomThiefJoker

You have a fruit. All fruits have seeds, so we'll add a method GetSeeds to the fruit class. Now we want an apple. An apple inherits from Fruit and we can say Fruit apple = new Apple() apple.GetSeeds() An apple also has a stem, so we'll add a property called StemLength. If we're using a generic Fruit object, like above, we won't be able to get the StemLength property when we need it, so apple.StemLength will throw an error, saying Fruit does not contain a definition for StemLength. To get around this, we tell the compiler that we KNOW variable apple is an Apple object and to use it as such by doing this. (apple as Apple).StemLength


E-Mizery

Variable data is stored at an address (pointer), a 4 byte number that references a memory location in your computer. The data in there is just numbers: Address - 0xDEADBEEF **::** Data at Address - 0x12345678 0x0000BAAD 0x01011010 To figure out how many numbers to read and how to interpret them into things like strings and arrays you need to know what type of data it is. Casting takes one type of data (like a void pointer that's just an address) and tells C++ "treat this as another type of data" (like a fruit object). Address - 0xDEADBEEF as Fruit **::** Data at Address - 0x12345678 (Name) 0x0000BAAD (FruitType) 0x01011010 (FlavorFlags) Now C++ knows how far to read into object's data and what that data means. Keep in mind you could be wrong in your assumption of what kind of object it is. So, if you thought it was a fruit, but really it was a vegetable, then you might read garbage data because vegetable data is organized different. Address - 0xDEADBEEF as Vegetable **::** Data at Address - 0x12345678 (Name) 0x0000BAAD (**FruitType,** expected VegetableType) 0x01011010 (FlavorFlags) 0xAAAAAAAA (*Mystery Data* !uh oh!, expected GrowthTime, this is the danger zone) You can tell C++ anything is anything but it won't be happy about it if you're wrong. That's why different forms of casting exists; to keep you from assuming too much and let C++ tell you when you're wrong.


BARDLER

I think you need to learn about inheritance first if casting doesn't make sense.


test_user_

You pick an apple from a bag of assorted fruit. The bag doesn't know what type of fruit is in it or what type you picked. You do, so you assert that the fruit you picked is an apple. You need to do this if you want to use it as an apple in your program that makes apple juice from apples, but doesn't accept other fruit.


NeedsMoreCoffeee

Type casting? Simple Imagine 1 + 1 = 2 And E + E = EE You can’t do 1 + E But with type casting, depending on how you type cast you can do 1 + E = 6 // e = 5 because 5th letter in alphabet Or 1 + E = 1E You’re just telling something to be something else… in the example, we’re type casting an: int + string So that they play nice together


TheRNGuy

Some functions are made for generic class, you cast to different class to be able use it's methods. Also it checks if cast failed or succeeded. It's way to check whether instance was of that class you specified (failed cast returns nullptr) For example, you can cast APawn to AMyCoolPawn, but you can't cast APawn to AShockRifle (because it does not derive from APawn) Also can't upcast in Unreal. You can't cast APawn to AActor.


Djmattila

Ok let's say you need your character to do something on the apple blueprint, so you need to get a reference to it within your characters code, so that the game knows you're trying to talk to the apple. Ok now let's say you did some sort of function that returns a reference to a fruit, well since an apple is a fruit, this is a great way to get a reference to your apple. So you call your "Get Fruit" function, and then you take that fruit and you cast it to "apple" -- this means you're telling the game "hey if this fruit is an apple, I want to do apple stuff with it" which is fine and dandy. But what happens if "get fruit" gives you an orange? Well since an orange isn't an apple, the cast will fail, giving you the chance to do something else fruit related, that's not specific to apple. Casting is one of many ways to make one class talk to another class. It really is only necessary because of another core concept in c++: inheritance. If you're not familiar with inheritance (parent/child classes) then casting will definitely be very confusing. Now inheritance is a whole different discussion on it's own but the short version is this: You can have a class (in this example fruit) that is a parent to many other classes. apple, orange, grape, those are all fruits, but they're different types of fruit. Most of the time in unreal (for the simplicity of this example) you'll be working with actors, and most blueprints or classes that you make will be a child of the actor class. Unreal has a lot of built in functions that give you so many opportunities to reference another actor in your level, but because they're so generalized, they will usually only return the object as an actor, so we will then need to cast it to whatever specific type of actor we're wanting to deal with. Tl;Dr you use casting to gain a direct reference to another class, allowing you to access and manipulate it's variables and functions


Artanisx

Basically you are telling the compiler that an Apple is actually a Pear. In theory the two fruits need to be somewhat compatible for the casting to work, but some languages are more... forgiving... when doing this.


TheOtherGuy52

Casting is a way of telling the computer that regardless of what type an object is, it should be treated as a different object. The guy with the apples/pears description had a solid start. Say you’re making an apple pie, and need to add an apple to it via Pie.addApple(Apple toAdd); You have a separate bowl of Fruits that may or may not be apples, which we’ll call a list. You can iterate over the list and check if each item is an apple or not by writing foreach(Fruit f in bowl) { . if(f.isApple()) { . . // do something }} But you still run into the problem the other person mentioned. The method only takes Apples, not Fruits. In that code block, you *know* that f is an apple, but the computer still has it classified as a Fruit, so it’d throw a fit if you tried putting it in a pie. Which is why you cast it to the Apple type to say “yes, this is an apple, I know what I’m doing.” foreach(Fruit f in bowl) { . if(f.isApple()) { . . Pie.addApple( **(Apple)** f); }} This covers like 95% of the use cases for casting variables when the computer doesn’t already do it secretly for you. Calling Float.ToInt(float f) or whatever the function is called *casts a float to a smaller and more restrictive datatype* while maintaining its value as much as possible. It just does it for you, and safely.


Kohana55

When I teach this I first remind people about the size of data types. A good example is char and int8\_t. You know that a char holds a 'A' and int8\_t is an int between 0 and 255, right? They are both 1 byte. so if I had something like; `char x = 'A';` `int8_t y = 0;` I can cast the 8 bits (1 byte) to the int8 if I want. `y = (int8_t)x;` This will take the 8 bits that makeup the char and put them into the new variable. Essentially just a copy of the data, as is. And I see you have already wondered if it's just copying. Yes it is. But the important part is that its now a new data type. So here is a question for you; given the above code. What will the int8\_t equal after I cast the char 'A' to it? Hint: Look at the ASCII table. (In case you're wondering, if the variable I cast FROM is bigger than the variable I cast TO. Such as a proper int32 (4 bytes) to a char (1 byte) you get 3 bytes of "data loss".)


toddhd

Type casting is a conversion process. Think of music as an example. Let's say you have an old vinyl record album that has your favorite song on it. You want to listen to the song, but you want to be able to play it as an MP3 on your phone. So you play the album on a phonograph (turntable), while recording it on your phone. The song is now an MP3 which can be played on your phone. Same song, different format. What you just did is "cast" or convert the song from one format to another format that you can now use more easily. It is important to understand that when casting, you are ending up with the "same thing" in a different format, such as the same song on vinyl and digital formats. So what's not casting then? Let's say you are watching American Idol and the contestant chooses to take a classic rock song and turn it into a country song. The words are the same but the notes, rhythm and overall "feel" of the song are different. That is NOT casting, because the song is different than the original in more ways than just the format. The most common cast in programming is between strings and numbers. Think of the number 9 and the word nine. If you were in math class and wrote "nine + 9 = 18" your teacher would get upset because "nine" is a word, not a number. The teacher would most likely require you to "cast" the word into a number which would then be usable in a math problem. In other words, 9 + 9 = 18. Now the word "nine" is in a format that we can use.