Object Oriented Programming in C++

  1. What is OOP

    OOP stands for Object-Oriented Programming.
    Procedural programming is about writing procedures or functions that perform operations on the data, while object-oriented programming is about creating objects that contain both data and functions. OOP is faster and easier to execute and it helps code not to repeat and makes it easier to maintain modify and debug.

  2. Classes and objects

    Class is a template definition of the methods and variables in a particular kind of object. Class is like your own type that can group some data and hold them in one place. Defaultly class members are private
    Struct works the same as class but default members are public. Object is instance of class that actually holds data defined in class.

    • Class creation
      To define class you use class keyword and name

      // defines a class with a and b
      class someClass{
         int a;
         int b;
      };
    • Functions in classes
      Methods are functions defined in classes To create method you just write function in class

      class someClass{
         int add(int a, int b){
            return a + b;
         }
      };
    • Object creation To create object from class you create variable of class type

      someClass obj;
    • Access member variables To access member variables you use . operator.

      struct someClass{
         int x;
         int y;
      };
      someClass obj;
       
      obj.x = 5 // sets x to 5
       
  3. Access modifiers

    Access modifiers are keywords that are used to specify accessbility of member variables and methods(functions).
    There are 3 types of them:

    • public
      Everything is exposed publicly. You can modify everything that is public.
      To make member variables public you use public keyword and :
      class someClass{
      public:
         int a;
      };
    • private
      Members cannot be accessed from outside. You cannot modify anything private.
      To make member variables private you use private keyword or you dont specify any modifier
      beacause default modifier is private.
      class someClass{
      private:
         int a;
      };
    • protected Members cannot be accessed from outside class, but they can be accessed in inherited classes.
      class someClass{
      protected:
         int a;
      };
  4. Constructors and Destructors

    • Constructor
      Constructor is a method that runs every time instance of class is created. To create constructor you dont specify type but name. It must be the same as the name of the class.

       class someClass{
          someClass(){
             // some code here
          }
       };

      You can now initialize object with constructor

      someClass obj1(5);
    • Destructor
      Destructor is a method that runs every time instance of class is destroyed. To create destructor you put ~ symbol and the name of the class.

       class someClass{
          someClass(){
             // constructor
          }
       
          ~someClass(){
             // destructor
          }
       };
       
  5. Constructor member initializer list

    Constructor member initializer list is a way to initialize variables. You can initialize variables in two ways:

    • Normaly
      Just using = operator

      class Entity{
      private:
         const char* m_value;
       
      public:
         Entity(){
         m_value = "Unknown";
         }
      };
    • Using member initializer list
      You write : after parameters and you write the name of variable and value in () that initializes your variable. Note that you need to initialize them in the same order that you declared them.

      class Entity{
      private:
         const char* m_value;
       
      public:
         Entity()
         : m_value("Unknown")
         {
       
         }
      };

      Using normal initialization in your constructor it is slightly slower than using member initializer list.

  6. Static

    The static keyword has different meanings when used with different context:

    • static in classes/struct
      It means that every instance of class would have all this one static variable/method. Static method cannot access non static variables

       struct someClass{
          static int count;
       };
       
       // you need to define count as member of 'someClass' to use it
       int someClass::count = 3;
       
       int main(){
          // every instance would have count set to 3 and there would be only 1 count instance not 3
          someClass instance1;
          someClass instance2;
          someClass instance3;
       
          std::cout << instance1.count; // count will be 3 for every instance
       }
       
       
       
    • static not in classes/struct
      It means that function/variable will be visible only in this translation unit

  7. Inheritance

    Inheritance a mechanism for sharing functionality between classes. A class can inherit from another class, which means that in addition to declaring its own attributes and methods, it also obtains those from the class from which it inherits. Child class will also have type of class it inherits from.
    We can inherit from class in 3 ways:

    • public inheritance
      Public members from parent class will be public in child class. Protected members will be protected.
    • private inheritance
      Public and Protected members from parent class will be private in child class.
    • protected inheritance
      Public and Protected members from parent class will be protected in child class. To inherit from another class we use : and then access specifier and then name of parent class

    Lets look at example. We create class entity that has x and y floats and move method. Then we create player class that would contain the same functionality as entity and something more. Instead of writing this:

    class Entity{
    public:
       float X, Y;
     
       void Move(float xa, float ya){
          X += xa;
          Y += ya;
       }
    };
     
    class Player{
    public:
       float X, Y;
     
       void Move(float xa, float ya){
          X += xa;
          Y += ya;
       }
    };

    We could use inheritance and write this:

    class Entity{
    public:
       float X, Y;
     
       void Move(float xa, float ya){
          X += xa;
          Y += ya;
       }
    };
     
    class Player :public Entity {
    public:
       int hp;
     
       void Damage(int damage){
          hp -= damage;
       }
    };

    Player would contain x, y and move also with hp and damage. The code is cleaner, it is not repetetive and it is better.

  8. Virtual functions

    Virtual function is a function that is declared in parent class and is re-defined (overriden) in child class. To create virtual function you use virtual keyword in parent class and override keyword in child class.

    class Entity {
    public:
       virtual const char* getName() {
          return "Entity";
       }
     
    };
     
    class Player : public Entity {
    private:
       const char* m_name;
    public:
       Player(const char* name) {
          m_name = name;
       }
       const char* getName() override{
          return m_name;
       }
    };
     

    There are also pure virtual functions. These are virtual functions that are not implemented in parent class and you are forced to implement in child class. You can only instantiate class that implemented those functions. To create one you write = 0 on the end of declaring function and rest is the same.

    class Entity {
    public:
       virtual const char* getName() = 0;
     
    };
     
    class Player : public Entity {
    private:
       const char* m_name;
    public:
       Player(const char* name) {
          m_name = name;
       }
       const char* getName() override{
          return m_name;
       }
    };
     
  9. Arrow Operator

    If your object is on the heap or you have pointer to an object you cant use ptr.something because you need to dereference it. Thats when arrow operator is usefull because it dereferences pointer and allows you to access something from that pointer.

    class Entity{
    private:
      int x;
    public:
      Entity() : x(1) {}
      int getX() const{
         return x;
      }
    };
     
    Entity e1;
    Entity* ptr = &e1;
     
    ptr -> getX() // gets value of x
     
  10. This keyword

    this keyword is a pointer to current object instance that method belongs to. this is only avaliable in object's methods.

    class Entity{
    private:
      int x,y;
    public:
      Entity(int x, int y){
         this -> x = x; // you get x value of this instance and put there value of parameter
         this -> y = y; // you get y value of this instance and put there value of parameter
      }
    };