


Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Virtual Function and Type Casting. Today's notes are primarily about casting, but first I want to talk about pure virtual functions and interfaces.
Typology: Exams
1 / 4
This page cannot be seen from the preview
Don't miss anything!



Today’s notes are primarily about casting, but first I want to talk about pure virtual functions and interfaces. Interfaces are a common and powerful form of abstraction. In some sense, they are the logical extreme of polymorphism. Polymorphism says the same general idea (or object) can take many shapes (hence the buzzword). Interfaces say they don’t care about the implementation (or “shape”) of the idea; they only care about the abstract services it provides. In Java, interfaces and objects are two different things. They have to be, since multiple inheritance is not allowed. A class cannot inherit both an interface and an implementation, so interfaces can’t be objects that have to be inherited. C++ is not burdened with this restriction. In C++, an interface is simply a class with one or more pure virtual methods. The idea of a pure virtual method is simple. We already talked about virtual methods, and how they are implemented through the virtual function pointer table (VFPT). This supports polymorphism by allowing a method to be invoked according to the type of an object as constructed, as opposed to the type of the object as lexically declared. But go back to my recurring polymorphism example: we have an Animal type, which is inherited by both Mammal and Fish. I defined a warm_up() method for Animal, because every animal has a way to warm up if needed. Mammals warm up by shivering; fish warm up by swimming upward toward warmer water. So each child class redefines warm_up, and as long as warm_up is virtual, every Animal warms up using the method that is appropriate for them. But how do I define the warm_up method for the Animal class? I need one, otherwise I can’t call warm_up for an Animal, defeating the polymorphism. In essence, I want to declare warm_up as part of an interface: all Animals must implement warm_up. So what do I put in this function? I could put the following in the Animal class:
What it type casting? Type casting is where you take an object of one type (for example integer), and make it another type (for example double). We often type cast primitives. We will also type cast up and down object hierarchies. Polymorphism relies on implicit type casting. Rarely, we will type cast other things. What is really going on when we type cast? It depends on what data type we are converting to what data type. If I type cast an int to a double, the underlying bit pattern has to change in order to keep the semantic value the same. Therefore when I type case an int to a double, the compiler inserts code (usually a function call) to change the underlying representation. On the other hand, if I cast an Animal* to a Mammal*, the underlying representation doesn’t change. No code is generated. The compiler just internally notes at compile time that the type of the pointer has changed. Type casting is made even more confusing because there are four ways to do it in C++: implicit, C-style, functional-style, and the new “best” style. In general, having too many ways to do the same thing is poor language style, but hey (not my fault). My recommendation is to limit yourself to implicit casting in certain safe situations, and new style casting otherwise. So let’s go over new style casting, which has 4 different types of casts. This can be confusing, but the idea is that the underlying semantics are exposed, making the code easier to read. And then I will tell you when I think they are necessary. Case #1: static casting. This is the most common cast. It is used to cast one related data type to another. For example, you can cast a double to an int, or vice-versa. The syntax is:
Case #3: reinterpret_cast. This is dangerous, but sometimes necessary. This cast says to reinterpret the compile-time type of a piece of data without touching it. For example, I could write: Double b = 3.1; Int a = reinterpret_cast