# 🔐 Understanding Access Modifiers in C++

## 🧠 Introduction

In Object-Oriented Programming (OOP), **data protection** is very important.  
Just like a real car hides its engine inside the bonnet, C++ also hides data inside a class.

To control *who can access what*, C++ provides **Access Modifiers**.

They decide the **visibility** of class members (data and functions).  
In short — they define **how much access** an object or a derived class has.

---

## 🧩 The Three Access Modifiers

| Modifier | Access Within Class | Access by Derived Class | Access by Object |
| --- | --- | --- | --- |
| **public** | ✅ Yes | ✅ Yes | ✅ Yes |
| **private** | ✅ Yes | ❌ No | ❌ No |
| **protected** | ✅ Yes | ✅ Yes | ❌ No |

Let’s understand these three using our **Car** example 🚗

---

## 🚘 1️⃣ Public Members

Public members are **open to everyone** —  
they can be accessed **inside the class**, **by derived classes**, and even **by objects**.

Let’s start with a simple class 👇

```plaintext
#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    int speed;

    void start() {
        cout << brand << " is starting..." << endl;
    }
};
```

### 🔍 Explanation:

* `brand` and `speed` are **public** — anyone can access them.
    
* You can easily change or read them using the object.
    

```plaintext
int main() {
    Car car1;
    car1.brand = "BMW";     // ✅ allowed
    car1.speed = 200;       // ✅ allowed
    car1.start();           // ✅ allowed
    return 0;
}
```

✅ Output:

```plaintext
BMW is starting...
```

✅ Everything works fine — because **public** = open access.

---

## 🔒 2️⃣ Private Members

Private members are **hidden** from the outside world.  
They can only be accessed **inside the same class**.

Let’s modify our class:

```plaintext
class Car {
private:
    string engineNumber; // private data

public:
    string brand;
    int speed;

    void setEngineNumber(string num) {
        engineNumber = num; // allowed (inside class)
    }

    void showDetails() {
        cout << "Brand: " << brand << endl;
        cout << "Speed: " << speed << " km/h" << endl;
        cout << "Engine No: " << engineNumber << endl;
    }
};
```

### 🔍 Explanation:

* `engineNumber` is **private** — only class functions can use it.
    
* We provide a **public function** (`setEngineNumber()`) to *safely modify* it.
    

```plaintext
int main() {
    Car car1;
    car1.brand = "Toyota";
    car1.speed = 150;

    // car1.engineNumber = "ENG123"; ❌ Not allowed (private)
    car1.setEngineNumber("ENG123");  // ✅ Allowed through public function

    car1.showDetails();
    return 0;
}
```

✅ Output:

```plaintext
Brand: Toyota
Speed: 150 km/h
Engine No: ENG123
```

🧠 Why use private?  
Because we don’t want anyone to directly change sensitive data like `engineNumber`.  
We protect it — just like a car’s engine is protected under the hood!

---

## 🛡️ 3️⃣ Protected Members

Protected members are a **special case** —  
they behave like private for normal objects,  
but are **accessible in derived classes**.

Let’s understand this by creating a **derived class** → `SportsCar` from `Car`.

```plaintext
class Car {
protected:
    int mileage;

public:
    string brand;
    int speed;

    void setMileage(int m) {
        mileage = m;
    }

    void showDetails() {
        cout << "Brand: " << brand << ", Speed: " << speed
             << ", Mileage: " << mileage << " km/l" << endl;
    }
};
```

Now we create a **derived class**:

```plaintext
class SportsCar : public Car {
public:
    void showSportsDetails() {
        cout << "🏎️ Sports Car Details: " << endl;
        cout << "Brand: " << brand << endl;     // ✅ public accessible
        cout << "Speed: " << speed << endl;     // ✅ public accessible
        cout << "Mileage: " << mileage << endl; // ✅ protected accessible
    }
};
```

And the `main()` function:

```plaintext
int main() {
    SportsCar sc;
    sc.brand = "Ferrari";
    sc.speed = 320;

    sc.setMileage(8); // using public function
    sc.showSportsDetails();

    // sc.mileage = 10; ❌ Not allowed (protected - can’t access from object)
    return 0;
}
```

✅ Output:

```plaintext
🏎️ Sports Car Details:
Brand: Ferrari
Speed: 320
Mileage: 8
```

---

## 🧩 Key Difference Between Access Modifiers

| Modifier | Access in Same Class | Access in Derived Class | Access by Object | Example |
| --- | --- | --- | --- | --- |
| **public** | ✅ | ✅ | ✅ | `brand`, `speed` |
| **private** | ✅ | ❌ | ❌ | `engineNumber` |
| **protected** | ✅ | ✅ | ❌ | `mileage` |

---

## 🏁 Real-Life Analogy

| Modifier | Real-World Meaning | Example in Car |
| --- | --- | --- |
| **public** | Open for everyone | Car color or brand (you can see it) |
| **private** | Hidden and secure | Engine number (not visible to users) |
| **protected** | Hidden from outside but visible to child models | Mileage info shared only with car engineers |

---

## 🎯 Final Summary

| Concept | Meaning | Used In Example |
| --- | --- | --- |
| **Public** | Accessible anywhere | `brand`, `speed`, `start()` |
| **Private** | Accessible only inside class | `engineNumber` |
| **Protected** | Accessible inside class & derived class | `mileage` |
