Skip to content

Classes_objects

Object-Oriented Programming (OOP) is a programming paradigm that organizes code around “objects” rather than functions. In this chapter, you’ll learn about classes, the blueprints for creating objects, and how to use them effectively in C++.

OOP is based on several key concepts:

┌─────────────────────────────────────────────────────────────┐
│ Object-Oriented Programming Concepts │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
│ │Classes │───▶│ Objects │───▶│ Encapsulation│ │
│ │(Blueprints) │(Instances) │ (Data hiding) │ │
│ └─────────┘ └─────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
│ │Inheritance│ │ Polymorphism│ │ Abstraction │ │
│ │(Reuse) │ │(Many forms) │ (Simplify) │ │
│ └─────────┘ └─────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Both classes and structs can contain data and functions. The main difference is default access specifier:

FeatureClassStruct
Default accessprivatepublic
Use forData hiding, OOPSimple data containers
// Class - members are private by default
class Circle {
double radius; // private by default
public:
double getRadius() { return radius; }
void setRadius(double r) { radius = r; }
};
// Struct - members are public by default
struct Point {
double x; // public by default
double y; // public by default
};
Rectangle.h
class Rectangle {
private:
double width;
double height;
public:
// Constructor
Rectangle(double w, double h);
// Member functions
double area() const;
double perimeter() const;
void resize(double newWidth, double newHeight);
// Getters
double getWidth() const { return width; }
double getHeight() const { return height; }
};
// Rectangle.cpp
#include "Rectangle.h"
Rectangle::Rectangle(double w, double h) : width(w), height(h) {}
double Rectangle::area() const {
return width * height;
}
double Rectangle::perimeter() const {
return 2 * (width + height);
}
void Rectangle::resize(double newWidth, double newHeight) {
width = newWidth;
height = newHeight;
}
#include <iostream>
int main() {
// Create objects
Rectangle rect1(5, 3);
Rectangle rect2(10, 7);
// Use member functions
std::cout << "Area: " << rect1.area() << std::endl;
std::cout << "Perimeter: " << rect2.perimeter() << std::endl;
// Modify object
rect1.resize(8, 4);
std::cout << "New area: " << rect1.area() << std::endl;
return 0;
}
class BankAccount {
private:
std::string accountNumber;
std::string ownerName;
double balance;
bool isActive;
};
class BankAccount {
public:
// Getter
double getBalance() const {
return balance;
}
// Setter
void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
// Withdraw returns success/failure
bool withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
return true;
}
return false;
}
};

this is a pointer to the current object:

class Person {
private:
std::string name;
int age;
public:
void setName(const std::string& name) {
this->name = name; // Distinguish parameter from member
}
// Returning reference to object (for chaining)
Person& setAge(int age) {
this->age = age;
return *this;
}
};

C++ provides three levels of access control:

SpecifierSame ClassDerived ClassOutside
private
protected
public
class Base {
private:
int privateVar; // Only Base can access
protected:
int protectedVar; // Base and derived classes
public:
int publicVar; // Everyone can access
};
#include <iostream>
#include <string>
#include <vector>
class BankAccount {
private:
std::string accountNumber;
std::string ownerName;
double balance;
bool isActive;
public:
// Constructor
BankAccount(const std::string& number, const std::string& owner, double initialBalance = 0)
: accountNumber(number), ownerName(owner), balance(initialBalance), isActive(true) {}
// Getter methods
std::string getAccountNumber() const { return accountNumber; }
std::string getOwnerName() const { return ownerName; }
double getBalance() const { return balance; }
bool getIsActive() const { return isActive; }
// Transaction methods
void deposit(double amount) {
if (amount > 0 && isActive) {
balance += amount;
std::cout << "Deposited: $" << amount << std::endl;
}
}
bool withdraw(double amount) {
if (amount > 0 && amount <= balance && isActive) {
balance -= amount;
std::cout << "Withdrawn: $" << amount << std::endl;
return true;
}
std::cout << "Withdrawal failed!" << std::endl;
return false;
}
// Account management
void close() {
isActive = false;
std::cout << "Account closed." << std::endl;
}
void display() const {
std::cout << "Account: " << accountNumber << std::endl;
std::cout << "Owner: " << ownerName << std::endl;
std::cout << "Balance: $" << balance << std::endl;
std::cout << "Status: " << (isActive ? "Active" : "Closed") << std::endl;
}
};
int main() {
// Create account
BankAccount account("123456789", "John Doe", 1000);
// Display account info
account.display();
std::cout << std::endl;
// Make transactions
account.deposit(500);
account.withdraw(200);
account.withdraw(2000); // Should fail
std::cout << std::endl;
account.display();
return 0;
}

Output:

Account: 123456789
Owner: John Doe
Balance: $1000
Status: Active
Deposited: $500
Withdrawn: $200
Withdrawal failed!
Account: 123456789
Owner: John Doe
Balance: $1300
Status: Active
┌─────────────────────────────────────────────┐
│ Class (Blueprint) │
│ ┌─────────────────────────────────────┐ │
│ │ class BankAccount │ │
│ │ { │ │
│ │ - accountNumber │ │
│ │ - ownerName │ │
│ │ - balance │ │
│ │ + deposit() │ │
│ │ + withdraw() │ │
│ │ + getBalance() │ │
│ │ } │ │
│ └─────────────────────────────────────┘ │
│ │ │ │
│ │ creates │ uses │
│ ▼ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ Objects (Instances) │ │
│ │ │ │
│ │ account1 account2 │ │
│ │ ───────── ───────── │ │
│ │ "12345" "67890" │ │
│ │ "John" "Jane" │ │
│ │ $1000 $5000 │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
// Bad - just a data container
struct Person {
std::string name;
int age;
};
// Good - data + behavior
class Person {
private:
std::string name;
int age;
public:
void setName(const std::string& n) { name = n; }
void setAge(int a) {
if (a >= 0) age = a;
}
std::string getName() const { return name; }
int getAge() const { return age; }
};
class MyClass {
public:
int getValue() const { // const means doesn't modify object
return value;
}
};
class MyClass {
private:
int value;
std::string name;
public:
MyClass() : value(0), name("default") {}
MyClass(int v, const std::string& n) : value(v), name(n) {}
};
  • Header: MyClass.h
  • Implementation: MyClass.cpp
  • A class is a blueprint for creating objects
  • Objects are instances of classes
  • Classes combine data (attributes) and functions (methods)
  • Access specifiers (public, private, protected) control visibility
  • private is default for classes, public is default for structs
  • The this pointer refers to the current object
  • Use meaningful names and keep classes focused on one responsibility

Now let’s learn about constructors and destructors, which manage object lifetime.

Next Chapter: 09_constructors_destructors.md - Constructors and Destructors