**Discussion 10: Polymorphism and Virtual Functions**
10/27, 10/29
[(back to course webpage)](./mcs360_fall2020.html)
# Inheritance and Protected Members
Recall that:
+ Parent's private members don't get inherited
+ Parent's protected and public members get inherited
+ Parent's protected and public members are Child's private by default
+ `class Child: public Parent` would inherit public members of Parent as public members of Child
# Polymorphism (look [here](https://www.cplusplus.com/doc/tutorial/polymorphism/) for a comprehensive tutorial)
Polymorphism is when the same class can have two different children inheriting from it. For example, both rectangles and triangles are shapes with some height and some width property, but they have different areas.
## Example
Let us look at the following code for a shape class and its children, Triangle and Rectangle:
```cpp
#include
class Shape {
protected:
double height, width;
public:
Shape() {
height = 0;
width = 0;
}
Shape(double h, double w) {
height = h;
width = w;
}
double area() {
std::cout << "Shape is not defined, so area is not computable\n";
return -1;
}
void dilate(double alpha) {
height *= alpha;
width *= alpha;
}
};
class Rectangle: public Shape {
public:
Rectangle(double h, double w):Shape(h, w) {
}
double area() {
return height * width;
}
};
class Triangle: public Shape{
public:
Triangle(double h, double w):Shape(h, w) {
}
double area() {
return 0.5 * height * width;
}
};
```
If you now have a rectangle `R(10,5)` and a triangle `T(10,5)` and print `R.area()` and `T.area()`, you will get 50 and 25, respectively.
## Shape pointer pointing to both `R` and `T`
Interestingly, you can have a `Shape* s` pointing to both `R` and `T` by doing `s = &R`, but when you try printing `s->area()` you would only print the Shape's area function.
# Virtual Functions
Virtual functions let you define functions in the class Shape that can be redefined in its children!
To define `Shape::area()` as a virtual function, just declare it as `virtual double Shape::area()`.
Then `s->area()` would call the area function of the children instead of the parent!
# Full CPP Code with Output
```cpp
#include
class Shape {
protected:
double height, width;
public:
Shape() {
height = 0;
width = 0;
}
Shape(double h, double w) {
height = h;
width = w;
}
double area() {
std::cout << "Shape is not defined, so area is not computable\n";
return -1;
}
void dilate(double alpha) {
height *= alpha;
width *= alpha;
}
};
class Rectangle: public Shape {
public:
Rectangle(double h, double w):Shape(h, w) {
}
double area() {
return height * width;
}
};
class Triangle: public Shape{
public:
Triangle(double h, double w):Shape(h, w) {
}
double area() {
return 0.5 * height * width;
}
};
int main() {
Rectangle R(10,5);
Triangle T(10,5);
std::cout << R.area() << "\n";
std::cout << T.area() << "\n";
Shape* s;
s = &R;
std::cout << s->area() << '\n';
s = &T;
std::cout << s->area() << std::endl;
return 0;
}
```
## Output with virtual keyword
```
(base) potla@EKR:~/Desktop/mcs360$ ./d10
200
100
200
100
```
## Output without virtual keyword
```
(base) potla@EKR:~/Desktop/mcs360$ ./d10
50
25
Shape is not defined, so area is not computable
-1
Shape is not defined, so area is not computable
-1
```