[C++] OOPs - Classes and Objects and Access Specifiers
Hey, have you ever wondered why C++ made such a big deal about "classes" and "objects"? I mean, why did we need them at all when C already had structs and functions?
That’s exactly what I was thinking! Like, we already had ways to organize data. So what problem were we trying to solve?
Great question. Let’s rewind a bit. Imagine we’re building a car simulation in C. We have variables like carSpeed, carFuel, carModel, and functions like accelerate(), brake(), refuel(). Over time, as we add more features — say, a dozen types of vehicles with their own quirks — this becomes a spaghetti mess. Everything’s global, or we pass endless parameters around. One bug and boom — chaos.
Yeah, that sounds hard to manage. Especially if we want to simulate hundreds of cars at once!
Exactly. That’s where Object-Oriented Programming (OOP) steps in, with its knight in shining armor — the class.
What’s a Class Really?
So, what exactly is a class?
Hmm… a class is like a blueprint?
Spot on! Just like how a blueprint defines how a house is built but doesn’t build a house itself, a class defines what an object will look like — its data and the functions that operate on that data. But until we create an actual object, nothing really exists.
Think of it like this — a class is a plan; an object is the real-world implementation.
Defining a Class in C++
You: Alright, so how do we write a class in C++?
Me: Simple. We use the class keyword, give it a name, and then define its members inside curly braces. Here’s an example:
class Car {
public:
string model;
float speed;
float fuel;
void accelerate() {
speed += 10;
}
void brake() {
speed -= 10;
}
};
Wait — what’s that public: keyword doing there?
Access Specifiers: public, private, protected
Ah! This is where things get spicy. In C++, every class member can be marked as either public, private, or protected. This controls who can access what.
Let’s go step-by-step:
Public
So public means everyone can access it?
Yup. If a variable or function is marked public, anyone with access to the object can use it.
Car myCar;
myCar.model = "Tesla";
myCar.accelerate();
Private
What if I want to keep things secret? Like internal calculations or sensitive data?Then you use private. It means only the class itself (and its friend functions) can access it.
class BankAccount {
private:
float balance;
public:
void deposit(float amount) {
balance += amount;
}
float getBalance() {
return balance;
}
};
Now, trying to do account.balance = 1000; from outside the class would throw an error. You have to use the public methods.
Protected
And what about protected?
That’s an interesting one. It's like private, but it allows derived classes (a.k.a. subclasses) to access the data. We’ll talk about those in a minute.
Creating Objects from Classes
So we’ve defined our class — how do we actually use it?
We create objects using the class as a type, just like int or float.
Car car1;
Car car2;
Each object gets its own copy of the member variables. So car1.speed and car2.speed are independent!
Classes vs Structs in C++
Wait — isn’t this similar to structs?
You’re absolutely right! In C++, structs and classes are very similar. The key difference?
By default:
- Members in class are private
- Members in struct are public
Example:
struct Student {
string name;
int roll;
};
Here, name and roll are public by default.
In practice, we usually use class when we're doing OOP, and struct for simple data containers — like Point, Pair, etc.
Let’s Use Member Functions Properly
So far, we’ve been writing functions inside the class body. Is that always a good idea?
Not always. You can define the function outside the class using the scope resolution operator :: .
class Car {
private:
float speed;
public:
void accelerate();
};
void Car::accelerate() {
speed += 10;
}
Hmm, why split them?
It helps in organizing larger programs. Keep the declaration in a header file, and the definitions in a .cpp file. It’s cleaner and more modular.
Encapsulation in Action
So when we bundle data and related functions together, that’s encapsulation, right?
Exactly. It's one of the four core principles of OOP — encapsulation, inheritance, polymorphism, and abstraction. Classes are the main tool for encapsulation.
We control who sees what using access specifiers. And we expose a clean interface through public methods while hiding complexity inside private members.
Sub-classes (a.k.a Derived Classes)
Okay, let’s come back to what you said earlier — "derived classes". What’s that?
Great memory! Let’s say we have a base class Vehicle. We can then inherit from it to create more specific classes like Car, Truck, Bike.
class Vehicle {
protected:
float speed;
public:
void setSpeed(float s) {
speed = s;
}
};
class Car : public Vehicle {
public:
void boost() {
speed += 50;
}
};
Now, Car inherits setSpeed() from Vehicle, and can also define its own behavior like boost().
Real-Life Example: Student Record System
Let’s make this real. Say, we’re building a student record system. How do classes help?
Perfect use case! We could define a Student class like this:
class Student {
private:
string name;
int rollNumber;
float marks;
public:
void setDetails(string n, int r, float m) {
name = n;
rollNumber = r;
marks = m;
}
void display() {
cout << "Name: " << name << ", Roll No: " << rollNumber << ", Marks: " << marks << endl;
}
};
Then we can create many student objects like:
Student s1, s2;
s1.setDetails("Alice", 101, 92.5);
s2.setDetails("Bob", 102, 88.0);
s1.display();
s2.display();
Each student has their own copy of the data. Clean, modular, and super easy to maintain.
Recap — Why Are Classes Awesome?
So to sum it up, why do we use classes again?
- To organize related data and behavior in one place.
- To control access using public/private/protected.
- To create reusable and modular code.
- To support inheritance for code reuse.
- To achieve encapsulation and hide internal complexity.
Final Thoughts
We see it now. Classes are not just syntax — they bring structure, clarity, and power.
That’s the spirit. Think of classes as your toolkit to manage the complexity of real-world problems in code. And remember, the moment your C code starts getting messy with dozens of variables and functions, it’s probably time to switch to OOP!