User Tools

Site Tools


notes:cprog:fall2021:projects:oop2

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
notes:cprog:fall2021:projects:oop2 [2021/11/09 02:29] – [Polymorphism] pleblancnotes:cprog:fall2021:projects:oop2 [2021/11/11 04:58] (current) – [References] hhemler
Line 20: Line 20:
 ====Polymorphism==== ====Polymorphism====
  
-==Compile Time Polymorphism==+Polymorphism, in C++, refers to a hierarchy of classes which are all related through inheritance.  This means that a call to a member function, will cause a different function to take place, depending on the type of object that calls the function.   
 + 
 +===Compile Time Polymorphism===
 Compile time polymorphism is achieved by overloading. This can be in the form of operator overloading, function overloading, or with templates. Compile time polymorphism is achieved by overloading. This can be in the form of operator overloading, function overloading, or with templates.
  
-==Run Time Polymorphism==+Overloading is takes place when more than one function or operator, with the same name and scope, are given differing definitions.  When this happens, the compiler will determine which definition is most appropriate, which is called overload resolution.   
 + 
 +It is called compile-time polymorphism because a function is called at the time of program compilation.  
 + 
 +==Template Functions== 
 +Templates are used to create functions that work with multiple types. At compile time the compiler will substitute the template type with the type given at the function's call. 
 + 
 +<code cpp> 
 +#include <cstdio> 
 + 
 +struct Foo; 
 + 
 +template<typename T> 
 +const char* is_nullptr(T var) 
 +
 + if (var == nullptr) 
 + return "nullptr"; 
 + else 
 + return "NOT nullptr"; 
 +
 + 
 +int main() 
 +
 + int x{ 5 }; 
 + int* xPtr{ &x }; 
 + long* nullPtr{ nullptr }; 
 + Foo* fooPtr{ nullptr }; 
 + 
 + std::printf("xPtr is %s\n", is_nullptr(xPtr)); 
 + std::printf("nullPtr is %s\n", is_nullptr(nullPtr)); 
 + std::printf("fooPtr is %s\n", is_nullptr(fooPtr)); 
 + 
 + return 0; 
 +
 +</code> 
 +In this example you can call is_nullptr with any type, at compile time the compiler will create three separate functions: one that takes int pointers, one that takes long pointers, and one that takes Foo pointers. 
 + 
 +This example produces this result: 
 +<cli> 
 +xPtr is NOT nullptr 
 +nullPtr is nullptr 
 +fooPtr is nullptr 
 +</cli> 
 +Templates help clean up your code and can be extremely powerful, especially when combined with type traits. 
 + 
 +===Run Time Polymorphism===
 Run time polymorphism is achieved by overriding. Overriding occurs when a child class redefines a parent class's member function. Run time polymorphism is achieved by overriding. Overriding occurs when a child class redefines a parent class's member function.
 +
 +In a runtime polymorphism, functions are called at the time of the program's execution.
  
 ==Virtual Functions== ==Virtual Functions==
 Using the __virtual__ keyword marks your functions as virtual. Virtual functions always call the most derived version of a member function. Using the __virtual__ keyword marks your functions as virtual. Virtual functions always call the most derived version of a member function.
 +
 +<code cpp>#include <cstdio>
 +
 +struct Rectangle
 +{
 + const char* type() const { return "Rectangle"; }
 +};
 +
 +struct Square : Rectangle
 +{
 + const char* type() const { return "Square"; }
 +};
 +
 +void print_type(const Rectangle& shape)
 +{
 + std::printf("%s\n", shape.type());
 +}
 +
 +int main()
 +{
 + const Rectangle rect;
 + const Square square;
 +
 + std::printf("Rectangle: ");
 + print_type(rect);
 + std::printf("Square: ");
 + print_type(square);
 +
 + return 0;
 +}
 +</code>
 +Running this code produces this result:
 +<cli>
 +Rectangle: Rectangle
 +Square: Rectangle
 +</cli>
 +However, with the addition of the __virtual__ keyword:
 +<code cpp>
 +virtual const char* type() const { return "Rectangle"; }
 +</code>
 +We now get the desired result:
 +<cli>
 +Rectangle: Rectangle
 +Square: Square
 +</cli>
 +//Notice objects deriving from Rectangle are passed by reference because if you pass by value a new Rectangle object will be created, therefore using Rectangle methods.//
 ====Access Control implications==== ====Access Control implications====
 +
 +Access control is important in polymorphism as it restricts or allows access to class members.  Assigning **public inheritance** will allow all other classes and functions to inherit that data or function.  Assigning **Private inheritance** will restrict access to a class member to functions within that same class.  The only exception taking place when a class is declared as a "friend."  **Protected** is similar to private, with the exception that protected class members can also be accessed by derived classes.  
 +
 +
  
 ====Parent-Child Relationships==== ====Parent-Child Relationships====
  
 +Parent child relationships refer to base classes and the derived classes that inherit from them.  In regards to polymorphism, this means, that the derived classes are not simply inheriting attributes or methods, but using them in different ways.  The methods and attributes being inherited still depends on that element's access control label.
 +
 +Inheritance lets us inherit attributes and methods from another class. Polymorphism uses those methods to perform different tasks.
 +====Similarities to word origins====
 +It is strange that what is called 'polymorphism' in C++ is called such. Polymorph's word structure would imply multiple shapes, and polymorph in common fantasy/magical settings often relates to something temporarily transforming into a different creature, or shape. This has no relation to the C++ polymorph, which mainly relates to a child class changing an already existing function of its parent classes. It seems that mutation or evolution would be a better term, as if a creature inherited something from its ancestors, such as eyes, and then the child some genetic variation that caused its eyes to be more effective at seeing, that would be a mutation or evolution, we would not call such a thing polymorphing.
 +
 +COOL BUG FACT: After writing this I found that "polymorph" and "polymorphism" have two very different meanings. Polymorphism is the occurrence of different forms among members of a colony, meaning everything I wrote above this is kinda wrong...
 +
 +RELEVANT COOL BUG FACT: If the child class has a child of its own, the polymorphed version of functions will be what the child's child inherits
 =====Program===== =====Program=====
 Write a program that makes use of polymorphism. It can be anything, so long as you genuinely implement it and it works. Write a program that makes use of polymorphism. It can be anything, so long as you genuinely implement it and it works.
Line 40: Line 148:
  
 =====References===== =====References=====
 +  * https://www.learncpp.com/cpp-tutorial/virtual-functions/ 
 +  * https://www.learncpp.com/cpp-tutorial/function-templates/ 
 +  * https://www.tutorialspoint.com/cplusplus/cpp_polymorphism.htm 
 +  * https://www.programiz.com/cpp-programming/access-modifiers 
 +  * https://www.w3schools.com/cpp/cpp_polymorphism.asp 
 +  * https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm 
 +  * https://www.mygreatlearning.com/blog/polymorphism-in-cpp/ 
 +  * https://www.javatpoint.com/cpp-virtual-function
 =====Submission===== =====Submission=====
 I'll be looking for the following: I'll be looking for the following:
notes/cprog/fall2021/projects/oop2.1636424955.txt.gz · Last modified: 2021/11/09 02:29 by pleblanc