Chapter 10: Classes & Objects
Classes & Objects in C++: The Heart of Object-Oriented Programming!
Hello my wonderful student! π Welcome to Lesson 10 β Classes & Objects β the most important and exciting chapter so far!
Up until now, weβve been writing procedural code β functions and data were separate. Now weβre entering the beautiful world of Object-Oriented Programming (OOP), where we combine data and functions that operate on that data into a single unit called a class.
Think of a class as a blueprint (like the design of a car), and an object as the actual thing created from that blueprint (like a real red Toyota car).
Today weβll cover everything step-by-step:
- What is a class and how to define it
- Objects β creating instances
- Constructors (default, parameterized, copy, move)
- Member variables (data) and member functions (behavior)
- The mysterious this pointer
Weβll go very slowly, with real-life analogies, tons of examples, visual explanations, common mistakes, and modern C++ best practices.
Letβs build our first real class together!
1. What is a Class? The Blueprint
Syntax to define a class:
|
0 1 2 3 4 5 6 7 8 9 10 |
class ClassName { public: // Access specifier (we'll talk about private later) // Member variables (data) // Member functions (behavior) }; |
Simple first example β Class Student
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include <iostream> #include <string> class Student { public: // Member variables (attributes / data) std::string name; int age; double gpa; // Member function (behavior / method) void introduce() { std::cout << "Hi! My name is " << name << ", I am " << age << " years old, " << "and my GPA is " << gpa << ".\n"; } }; int main() { // Creating objects (instances) from the class blueprint Student alice; alice.name = "Alice Johnson"; alice.age = 20; alice.gpa = 3.8; Student bob; bob.name = "Bob Smith"; bob.age = 21; bob.gpa = 3.5; // Using the member function alice.introduce(); bob.introduce(); return 0; } |
Output:
|
0 1 2 3 4 5 6 7 |
Hi! My name is Alice Johnson, I am 20 years old, and my GPA is 3.8. Hi! My name is Bob Smith, I am 21 years old, and my GPA is 3.5. |
Beautiful, right? Each Student object has its own copy of name, age, and gpa.
2. Constructors β Special Functions That Initialize Objects
A constructor is a special member function that is automatically called when an object is created. Its name is exactly the same as the class name, and it has no return type (not even void).
A. Default Constructor (No parameters)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class Student { public: std::string name; int age; double gpa; // Default constructor Student() { name = "Unknown"; age = 0; gpa = 0.0; std::cout << "Default constructor called!\n"; } }; int main() { Student s; // Calls default constructor s.introduce(); // Hi! My name is Unknown... } |
B. Parameterized Constructor (Recommended!)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
class Student { public: std::string name; int age; double gpa; // Parameterized constructor Student(std::string n, int a, double g) { name = n; age = a; gpa = g; std::cout << "Parameterized constructor called for " << name << "\n"; } void introduce() const { // const β promise not to modify object std::cout << "Hi! My name is " << name << ", age " << age << ", GPA " << gpa << ".\n"; } }; int main() { Student alice("Alice", 20, 3.8); // Calls parameterized constructor Student bob("Bob", 21, 3.5); alice.introduce(); bob.introduce(); } |
C. Constructor Initializer List (Modern & Best Practice)
Much more efficient β initializes members before the body runs.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
Student(std::string n, int a, double g) : name(std::move(n)), // move for efficiency age(a), gpa(g) { std::cout << "Initializer list constructor called!\n"; } |
D. Copy Constructor β Creates a copy of an existing object
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Copy constructor Student(const Student& other) : name(other.name), age(other.age), gpa(other.gpa) { std::cout << "Copy constructor called for " << name << "\n"; } int main() { Student alice("Alice", 20, 3.8); Student copyOfAlice = alice; // Calls copy constructor copyOfAlice.introduce(); } |
E. Move Constructor (C++11+) β Efficient transfer of resources
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
Student(Student&& other) noexcept : name(std::move(other.name)), age(other.age), gpa(other.gpa) { std::cout << "Move constructor called!\n"; } |
Modern rule (2025+): Always provide default, parameterized, and copy/move constructors when your class manages resources.
3. Member Functions vs. Free Functions
Member functions belong to the class and have access to all members (even private ones).
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class Rectangle { public: double width; double height; // Member function double area() const { return width * height; } }; int main() { Rectangle r{5.0, 3.0}; std::cout << "Area = " << r.area() << "\n"; // 15 } |
4. The this Pointer β Who Am I?
Inside a member function, there is a hidden pointer called this that points to the current object.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class Student { public: std::string name; void setName(const std::string& n) { this->name = n; // same as: name = n; // Useful when parameter name conflicts with member name } void introduce() const { std::cout << "I am " << this->name << "!\n"; } }; int main() { Student s; s.setName("Webliance"); s.introduce(); // I am Webliance! } |
Very common use: When parameter name is same as member name:
|
0 1 2 3 4 5 6 7 8 9 |
Student(std::string name, int age) : name(name), age(age) // Without 'this->' it would be ambiguous! { } |
5. Full Practical Example β Bank Account Class
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include <iostream> #include <string> class BankAccount { private: // We'll talk about access specifiers next lesson std::string accountHolder; double balance; public: // Constructors BankAccount() : accountHolder("Unknown"), balance(0.0) {} BankAccount(std::string holder, double initial) : accountHolder(std::move(holder)), balance(initial) { std::cout << "Account created for " << accountHolder << "\n"; } // Member functions void deposit(double amount) { if (amount > 0) { balance += amount; std::cout << "Deposited $" << amount << ". New balance: $" << balance << "\n"; } } bool withdraw(double amount) { if (amount > 0 && amount <= balance) { balance -= amount; std::cout << "Withdrew $" << amount << ". New balance: $" << balance << "\n"; return true; } std::cout << "Insufficient funds or invalid amount!\n"; return false; } double getBalance() const { return balance; } void display() const { std::cout << "Account Holder: " << accountHolder << " | Balance: $" << balance << "\n"; } }; int main() { BankAccount myAccount("Webliance", 5000.0); myAccount.display(); myAccount.deposit(1500.0); myAccount.withdraw(2000.0); myAccount.withdraw(10000.0); // fails std::cout << "Final balance: $" << myAccount.getBalance() << "\n"; return 0; } |
Your Mini Homework (Try These!)
- Create a Car class with members: brand, model, year, fuelLevel. Add constructors (default + parameterized) and member functions: drive() (reduce fuel), refuel(), displayInfo().
- Write a Point class with x and y (double). Add a member function distanceTo(const Point& other) that calculates Euclidean distance.
- Create a copy constructor for the BankAccount class and test it.
Youβre doing absolutely phenomenal! Youβve just learned the core of modern C++ β classes and objects are used everywhere: games, apps, web servers, AI librariesβ¦
Next lesson: Access Specifiers (public, private, protected) + Encapsulation β how to make classes safe and professional!
Any questions? Confused about constructors? Want more examples with this or move semantics? Just ask β your friendly C++ teacher is right here for you! π
