# Advance OOPS in C++ | A complete guide for Interviews

💡 Four Pillars of Object-Oriented Programming:

1. **Encapsulation**
    
2. **Inheritance**
    
3. **Abstraction**
    
4. **Polymorphism**
    

```cpp

// Human class
class Human {
private:
    string secret = "humansecret";

public:
    int age = 30, weight = 76;
};

// Student class
class Student : private Human {
public:
    string name = "student";
    void print() {
        cout << name << endl;
        cout << age << endl;
        cout << weight << endl;
    }
};

// GStudent class
class GStudent : public Student {
public:
    string name = "gstudent";
    void print() {
        cout << name << endl;
        cout << age << endl; // Inaccessible
        cout << weight << endl; // Inaccessible
    }
};

int main() {
    Student s1;
    // age, weight became private members of s1.
    cout << s1.age << endl; // Inaccessible
    cout << s1.weight << endl; // Inaccessible
    cout << s1.name << endl; // student
    s1.print(); // student 30 76

    GStudent g1;
    cout << g1.name << endl; // gstudent
    cout << g1.age << endl; // Inaccessible
    cout << g1.weight << endl; // Inaccessible

    return 0;
}
```

## Encapsulation

> To encapsulate something

The process of **grouping data members and corresponding methods into a single unit** is known as Encapsulation.

💡 **We can create a fully encapsulated class by making all the data members private**.

If the data members are private, they can only be accessed within the class; no other class can access that class’s data members.

### **Advantages of Encapsulation**

1. Encapsulation is a way to ***achieve data hiding*** because **other classes will not be able to access the data** through the private data members.
    
2. It helps hide the data’s internal information, enhancing **security**.
    
3. With encapsulation, you can make the **class read-only**.
    
4. Encapsulation promotes **code reusability**.
    
5. Encapsulated code is better for **unit testing**.
    

💡 Encapsulation also makes your code more testable, as you can isolate the unit of functionality that you want to test, and mock or stub the dependencies that you don't.

Summary: Data hiding, Security, Reusability of code, Testing.

[Encapsulation in C++ - GeeksforGeeks](https://www.geeksforgeeks.org/encapsulation-in-cpp/?ref=lbp)

## Inheritance \[Most Important\]

In C++, inheritance is a process in which one object automatically acquires all the properties and `behaviors` of its parent object. This allows you to reuse, extend, or modify the attributes and `behaviors` defined in other classes.

### Advantages of Inheritance

* The main advantage of inheritance is code `reusability`. We can reuse the code when we inherit the existing class’s methods and fields into a new class.
    
* **Runtime** `polymorphism` (method overriding) can only be achieved through inheritance.
    

### Modes of Inheritance

1. **Public mode**: If a subclass is derived from a public base class, the base class’s public members become public in the derived class, and protected members remain protected.
    
2. **Protected mode**: If a subclass is derived from a protected base class, both public and protected members of the base class become protected in the derived class.
    
3. **Private mode**: If a subclass is derived from a private base class, both public and protected members of the base class become private in the derived class. Private members of the parent class are not inherited.
    

| Base class visibility of members ⬇️ | Public | Private | Protected |
| --- | --- | --- | --- |
| Private (no inheritance) | Not Inherited | Not Inherited | Not Inherited |
| Protected | Protected | Private | Protected |
| Public | Public | Private | Protected |

> 💡 Private data members of the parent/super class can’t be inherited.

## Types of Inheritance

C++ supports **five types of inheritance**:

1. **Single Inheritance**  
    In single inheritance, one class can extend the functionality of another class. There is only one parent class and one child class.
    
    ```cpp
    class Animal {
    public:
        int age;
        int weight;
    
        void speak() {
            cout << "Speaking " << endl;
        }
    };
    
    class Dog: public Animal {
    };
    ```
    
2. **Multilevel Inheritance**  
    When a class inherits from a derived class, and the derived class becomes the base class of a new class, it is called multilevel inheritance.
    
    ```cpp
    class Animal {
    public:
        void speak() {
            cout << "Speaking " << endl;
        }
    };
    
    class Dog: public Animal {
    };
    
    class GermanShepherd: public Dog {
    };
    ```
    
3. **Multiple Inheritance**  
    In multiple inheritance, a class can inherit more than one class. A single child class can have multiple parent classes.
    
    ```cpp
    class Animal {
    public:
        void bark() {
            cout << "Barking " << endl;
        }
    };
    
    class Human {
    public:
        void speak() {
            cout << "Speaking " << endl;
        }
    };
    
    // Multiple Inheritance
    class HybridClassExample: public Animal, public Human {
    };
    ```
    
4. **Hierarchical Inheritance**  
    In hierarchical inheritance, one class serves as a base class for more than one derived class.
    
    ```cpp
    class A {
    public:
        void func1() {
            cout << "Inside Function 1" << endl;
        }
    };
    
    class B: public A {
    public:
        void func2() {
            cout << "Inside Function 2" << endl;
        }
    };
    
    class C: public A {
    public:
        void func3() {
            cout << "Inside Function 3" << endl;
        }
    };
    ```
    
5. **Hybrid Inheritance**  
    Hybrid inheritance is a combination of more than one type of inheritance.
    

## **Ambiguity (The Diamond Problem)**

Ambiguity arises when a class inherits member functions with the same name from two or more base classes, causing the compiler to be unsure which function to invoke.

### **Avoid Ambiguity Using Scope Resolution Operator**

The ambiguity can be resolved by using the **scope resolution operator** to specify the class in which the member function lies:

`object.class_name::method_name();`

```cpp
class A {
public:
    void func() {
        cout << " I am A" << endl;
    }
};

class B {
public:
    void func() {
        cout << " I am B" << endl;
    }
};

class C: public A, public B {
};

int main() {
    C obj;
    obj.A::func();
    obj.B::func();
    return 0;
}
```

Using the `virtual` keyword during inheritance avoids creating multiple copies of the same named variable/method.

[Hybrid Inheritance in C++ with Diamond Problem and its Resolution | Virtual Inheritance in C++](https://www.youtube.com/watch?v=DiUXoiOLZY0)

## **Polymorphism** \[Very Important\]

The term "`Polymorphism`" is derived from the Greek words "poly" + "morphs," meaning many forms.

For example, a woman behaves like a teacher in a classroom, a mother or daughter at home, and a customer in a market. A single person is behaving differently in various situations.

### Compile-Time Polymorphism

1. **Function Overloading**  
    When there are multiple functions with the same name but different parameters, these functions are said to be overloaded.
    
    ```cpp
    class Geeks {
    public:
        void func(int x) {
            cout << "value of x is " << x << endl;
        }
    
        void func(double x) {
            cout << "value of x is " << x << endl;
        }
    
        void func(int x, int y) {
            cout << "value of x and y is " << x << ", " << y << endl;
        }
    };
    
    int main() {
        Geeks obj1;
        obj1.func(7);
        obj1.func(9.132);
        obj1.func(85, 64);
        return 0;
    }
    ```
    
2. **Operator Overloading**  
    C++ allows overloading operators with special meanings for a data type.
    
    ```cpp
    class Complex {
    private:
        int real, imag;
    public:
        Complex(int r = 0, int i = 0) {
            real = r;
            imag = i;
        }
    
        Complex operator+(Complex const& obj) {
            Complex res;
            res.real = real + obj.real;
            res.imag = imag + obj.imag;
            return res;
        }
    
        void print() { cout << real << " + i" << imag << endl; }
    };
    
    int main() {
        Complex c1(10, 5), c2(2, 4);
        Complex c3 = c1 + c2;
        c3.print(); // 12 + i9
        cout << 3 + 4<< endl; // 7 
    }
    ```
    
    ### **Runtime Polymorphism**
    
    **(Method Overriding)**  
    A child class can provide its own version of an implementation without altering the original function.
    

```cpp

class Animal {
public:
 void speak() {
     cout << "Speaking " << endl;
 }
};

class Dog: public Animal {
public:
 void speak() {
     cout << "Barking " << endl;
 }
};

int main() {
 Dog d;
 d.speak(); // Barking
}
```

```cpp
class Animal {
public:
    void speak() {
        cout << "Speaking " << endl;
    }
};

class Dog: public Animal {
public:
    void speak() {
        cout << "Barking " << endl;
    }
};

int main() {
    Dog d;
    d.speak(); // Barking
}
```

> Virtual functions, abstract classes (pure virtual functions), method overriding, compile-time vs. runtime polymorphism.

## **Abstract Class**

An abstract class is a class that **can’t be instantiated** directly. These classes exist to serve as base classes for other derived classes. Abstract classes contain at least one **pure virtual function**.

💡 **We cannot create an object of an abstract class**.

```cpp
class Animal {
public:
    virtual void sound() = 0; // Pure Virtual Function
};

class Dog: public Animal {
public:
    void sound() {
        cout << "Bark" << endl;
    }
};
```

### **Why Use Abstract Classes?**

1. **Code Reusability**: You can define common functionalities in the abstract class and extend them in derived classes.
    
2. **Runtime Polymorphism**: Achieved using function overriding in derived classes.
    

[Pure Virtual Functions and Abstract Classes](https://www.geeksforgeeks.org/pure-virtual-functions-and-abstract-classes/)

## **Friend Function**

In C++, a `friend` function is a special function that **can access the private and protected data members of a class**.

💡 `Friend` functions are **not members of the class** but have the privilege to access private data.

```cpp
class Box {
private:
    int length;
public:
    Box() : length(0) {}
    friend int printLength(Box);
};

int printLength(Box b) {
    b.length += 10;
    return b.length;
}
```

**When to use friend functions:**

* If a function is not part of the class's functionality but needs to access its private or protected data.
    
* To enable operator overloading when the left operand is not an object of the class.
    

```cpp
class Box {
private:
    int length;
public:
    Box() : length(0) {}
    friend void setLength(Box&, int len);
    void displayLength() { cout << length << endl; }
};

void setLength(Box& b, int len) {
    b.length = len;
}
```

## **Destructor**

A **destructor** is a special member function that is executed whenever an object of its class goes out of scope or is explicitly deleted.

```cpp
class Person {
public:
    // Constructor
    Person() {
        cout << "Constructor is called." << endl;
    }

    // Destructor
    ~Person() {
        cout << "Destructor is called." << endl;
    }
};

int main() {
    Person p1;
    return 0;
}
```

> The `delete` keyword is used to deallocate memory and calls the destructor.

## **Virtual Destructor**

When we **delete a derived class object using a base class pointer**, the behavior is undefined if the destructor in the base class is not virtual.

```cpp
class Base {
public:
    virtual ~Base() {
        cout << "Base class destructor called" << endl;
    }
};

class Derived : public Base {
public:
    ~Derived() {
        cout << "Derived class destructor called" << endl;
    }
};

int main() {
    Base *b = new Derived();
    delete b;
    return 0;
}
```

## Abstraction Vs Encapsulation

**Abstraction is generalized term. i.e. Encapsulation is subset of Abstraction.**

| Abstraction | Encapsulation |
| --- | --- |
| It solves an issue at the design level. | Encapsulation solves an issue at implementation level. |
| hides the unnecessary detail but shows the essential information. | It hides the code and data into a single entity or unit so that the data can be protected from the outside world. |
| Focuses on the external lookout. | Focuses on internal working. |
| Lets focus on what an object does instead of how it does it. | Lets focus on how an object does something. |
| Example: Outer look of mobile, like it has a display screen and buttons. | Example: Inner details of mobile, how button and display screen connect with each other using circuits. |

[https://stackoverflow.com/questions/742341/difference-between-abstraction-and-encapsulation](https://stackoverflow.com/questions/742341/difference-between-abstraction-and-encapsulation)
