Classes & Objects
public and private access, how constructors bring objects to life, what the this pointer does, the getter/setter pattern, and a complete worked BankAccount class.
What Is a Class? What Is an Object?
Every C++ program you've written so far has used built-in types like int, double, and string. A class lets you define your own type — one that groups related data and the functions that operate on that data into a single unit.
A class is a blueprint. It describes what data an object will hold and what it can do — but it isn't a real thing by itself. An object is an actual instance created from that blueprint, living in memory with its own real values.
class keyword.Defining a Class in C++
You declare a class with the class keyword, followed by a name (by convention, PascalCase — Rectangle, not rectangle) and a body in curly braces, ending with a semicolon.
Inside the class, you control who can access each member using access specifiers: private members can only be used inside the class itself; public members can be used from anywhere the object is visible.
class Rectangle { private: double width; // member variable — hidden from outside double height; // member variable — hidden from outside public: void setWidth(double w) { width = w; } void setHeight(double h) { height = h; } double getArea() { return width * height; // member function using member data } };
class Rectangle { double width; ... } with no access specifier at all, width is private by default. A struct behaves the same way but defaults to public. This is the only real difference between class and struct in C++ — most programmers use class for objects with behaviour and keep data hidden.Constructors — Bringing Objects to Life
A constructor is a special member function that runs automatically whenever an object is created. It has the same name as the class and no return type — not even void. Constructors are the natural place to initialize member variables.
Rectangle r1;. Good for giving sensible starting values.Rectangle r2(4.0, 5.0);.#include <iostream> using namespace std; class Rectangle { private: double width; double height; public: // Default constructor Rectangle() { width = 1.0; height = 1.0; } // Parameterized constructor Rectangle(double w, double h) { width = w; height = h; } double getArea() { return width * height; } }; int main() { Rectangle r1; // calls the default constructor Rectangle r2(4.0, 5.0); // calls the parameterized constructor cout << "r1 area: " << r1.getArea() << endl; cout << "r2 area: " << r2.getArea() << endl; return 0; }
Output:
r1 area: 1 r2 area: 20
The this Pointer & the Getter/Setter Pattern
Inside any member function, this is a pointer to the object the function was called on. You rarely need it — but it's essential when a parameter has the same name as a member variable, since the parameter would otherwise "shadow" the member.
class Rectangle { private: double width; public: void setWidth(double width) { this->width = width; // this->width is the member, width is the parameter } double getWidth() const { return this->width; } };
A getter is a public method that returns the value of a private member (like getWidth() above). A setter is a public method that changes a private member, usually after validating the new value. Together they let you keep data private while still giving controlled access from outside the class.
width were public, any code anywhere could set it to -500. With a setter, you can reject invalid values: void setWidth(double w) { if (w > 0) width = w; }. This is encapsulation — one of the core ideas of OOP.Complete Worked Example — a BankAccount Class
Let's put everything together: private data, two constructors, and public methods that read and safely modify that data.
#include <iostream> #include <string> using namespace std; class BankAccount { private: string owner; double balance; public: // Default constructor BankAccount() { owner = "Unknown"; balance = 0.0; } // Parameterized constructor BankAccount(string ownerName, double initialBalance) { owner = ownerName; balance = initialBalance; } // Getters string getOwner() const { return owner; } double getBalance() const { return balance; } // Deposit — always allowed if positive void deposit(double amount) { if (amount > 0) { balance = balance + amount; } } // Withdraw — returns true only if it succeeded bool withdraw(double amount) { if (amount > 0 && amount <= balance) { balance = balance - amount; return true; } return false; } }; int main() { BankAccount acc1("Ayesha", 5000.0); acc1.deposit(1500.0); bool success = acc1.withdraw(2000.0); cout << acc1.getOwner() << "'s balance: " << acc1.getBalance() << endl; cout << "Withdrawal successful: " << success << endl; return 0; }
Output:
Ayesha's balance: 4500 Withdrawal successful: 1
Notice balance and owner are never touched directly from main() — every change goes through deposit() or withdraw(), which can enforce rules (like never allowing a negative balance). That's encapsulation in action.
Lesson Summary
private hides members from outside code; public exposes them. class defaults to private.this is a pointer to the current object — mainly used when a parameter name shadows a member name.class keyword (no access specifier written) are:this pointer refer to inside a member function?Now it's your turn to write real code. Complete the challenge below in any C++ compiler or online IDE.
Book class 📚Write a C++ program that defines a
Book class with these private members:
string title, string author, int pages
Give it a parameterized constructor that sets all three, and public getter methods:
getTitle(), getAuthor(), getPages(). In main(), create at least two Book objects and print their details using cout.
Bonus: Add a
bool isLongRead() method that returns true if pages > 400.
💡 Show hints if you're stuck
- Declare the three members under a
private:label - The constructor's name must exactly match the class name:
Book(string t, string a, int p) - Getters return the stored value:
string getTitle() const { return title; } - Create objects like
Book b1("1984", "George Orwell", 328);