C++ Polymorphism
Giothecoder (127)

I apologize in advance, this probably is a pretty bad tutorial.

Polymorphism, as defined on google, is "a feature of a programming language that allows routines to use variables of different types at different times."

There are a couple different ways of implementing polymorphism in c++ for different type of polymorphism.

An extremely common form of polymorphism is templates. I will give an example using a vector.
If you know what a vector is and how to use it, then great skip to the big dollar signs.
Otherwise, stay with me. This’ll be short.

The Vector Class

The vector class is a part of the STL(standard template library) that makes it easy to use dynamic arrays.
If you don’t know what a class is, then I’m sorry your on your own. Go look it up.
When using a vector, or any of the classes from the STL actually, we must initialize the class in a special way.
vector<data_type> name;
Where vector is the name of the class you are using, data_type is the type of data the container is holding, and name is the name of your variable.

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

When we initialize a vector this way, what’s really happening is that the compiler kinda makes a new type that’s an exact copy of the vector class, only an anonymous type that was being used in the class is now replaced with the data type you specified. It’s kinda like function overloading in a way.

Let’s make our own template class.

say I want to make a dynamic array, but don’t have access to vector like a normal person, so you decide to make a class. Now the problem is you don’t know what the data type of the array is going to be, so you decide to make a template class.
Ok.
Here we go.
To declare a template class or function, we must use the template keyword, along with a list of names of your unknown types inside angle brackets. They’ll start with either the class keyword or typename keyword.

template <typename Arr_T> // arr_t is the type of our array
class vec {
 // we can now use Arr_T in place of the type the user will later supply 
  Arr_T * array;
  int length:
  public:
  vec(){
    array = nullptr;
    length = 0;
  }
  Arr_T& operator[] (int pos){
    return array[pos];
  }
  void resize(int newLen){
    if(newLen == 0){
      if(array != nullptr)
        delete[] array;
      length = 0;
      array = nullptr;
      return;
    }
    Arr_T * oldArr = array; // again, using Arr_T as if it is an actual type
    array = new Arr_T[newLen];
    if(oldArr != nullptr){
      for(int i = 0;i < newLen && i < length;i++){
        array[i] = oldArr[i];
      }
      delete[] oldArr;
    }
    length = newLen;
  }
  bool empty(){
    return !!length;
  }
  int size(){
    return length;
  }
};

This is a form of polymorphism in the fact that it can handle any data type.
We can use the same keywords and all that in functions.

template <typename T>
void swap(T& x,T& y){
  T reg = x;
  x = y;
  y = reg;
}

To use the function (if your still a little confused), we simple call it with the extra special parameters int the angle brackets to tell us the type of the values being swapped.

int x = 0, y = 47;
std::cout << x << ' ' << y;
// 0 47
swap<int>(x,y); // int is the type of x and y. It will replace the T in swap.
std::cout << x << ' ' << y;
// 47 0

Another form of polymorphism is implemented through inheritance.

If you know what inheritance is , then skip to the big dollar signs.

This isn’t going to be a good explanation, so I suggest also looking it up if this doesn’t help.

inheritance is kinda like making extensions of a class. Specializations of it. These specializations receive everything the base class has, and stuff you build upon that.
Let’s say I have a 'parent' class called board. It’s 'children' classes that inherit from the base class would be let’s say.. snowboard and skateboard skateboard. They are children of board because they both have some similar properties (like you stand on them, they can be used for moving around...) but they are separate (skateboard is for the actual ground and has wheels and a grippy surface vs. you can’t even move on any type of ground that isn’t a slope and has snow with a snowboard and it has strap in thingies for your feet)
Another example (also a lot more common than mine lol) is the shape example.
Let’s say I have a parent class called Shape. Some children of Shape could be Quadrilateral or Triangle. These children will have special attributes that Shape does not have.

// Parent class 
class Shape {
  protected: // exact same thing as private, with one small change (more later)
  long double area;
};

class Quadrilateral 
: public Shape // syntax for declaring inheritance. More later.
{
  // has area, but it’s implicit; we inherited it from Shape.
  // add extra stuff specific to Quadrilaterals
  long double top_len, bottom_len;
  long double left_side_len, right_side_len;
};

class Triangle
: public Shape
{
  // has area, but it’s implicit; we inherited it from Shape
  // add extra stuff specific to Triangles.
  long double hypotenuse, leg1, leg2;
};

Now looking at the syntax I didn’t cover.
protected is a type of access specifier, like public or private that is basically the same exact thing as private, but protected data can be inherited by children vs private data cannot.
class C : access_specifier P states that the class C inherits from class P. access_specifier upgrades all members inherited from class P to that specifier if it’s under. For example if area had been a public member of Shape and Triangle had stated it’s access level to be private, then area would have become a private member of Triangle instead of a public member.

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

Right.
Uh.
So.
Say we have a game keeps track of every entity on the board by putting them all in a vector. Now usually this would be impossible (you’d probably use a tuple or something), because all your entities are of different class types, like weapon, player, vehicle... but luckily, you had them all inherit from a parent class - Entity! Yay! So, instead of making a tuple, you make a vector of pointers to Entities. Pointers to a parent class can point to any object of that class or any class that is it’s child. So in this case, the vector of pointers could point to a player or a weapon or a vehicle.

class Entity {
  
};

class Player : public Entity {

};

class Weapon : public Entity {

};

class Vehicle : public Entity {

};

int main(){
  std::vector<Entity*> stuff;
  stuff.push_back(new Weapon); // doesn’t care. Perfectly valid
  stuff.push_back(new Vehicle); // still Valid
  stuff.push_back(new Player); // still valid
  stuff.push_back(new Entity); // still valid
  stuff.push_back(new char); // NOPE! Throw error
}

Next up: https://repl.it/talk/learn/C-Ploymorphism-The-Good-Stuff/28359

You are viewing a single comment. View All
Giothecoder (127)

@SixBeeps oh. Ok. Thank you anyways though lol. :)