C++ PROGRAMMING:Module 8: Object-Oriented Programming (Classes)

Mastering module 8: object-oriented programming (classes) concepts and implementation.

Object-Oriented Programming (Classes)

Object-Oriented Programming (OOP) is a programming paradigm that organizes code around objects and classes. It's one of the most important concepts in modern C++.

What is OOP?

Object-Oriented Programming models real-world entities as objects that have:

  • Attributes (data/state)
  • Behaviors (functions/methods)

Key Principles:

  • Encapsulation: Bundling data and methods together
  • Abstraction: Hiding implementation details
  • Inheritance: Creating new classes from existing ones
  • Polymorphism: Same interface, different implementations

What is a Class?

A class is a blueprint or template for creating objects. It defines:

  • Data members (attributes/variables)
  • Member functions (methods/behaviors)

Analogy: A class is like a blueprint for a house, and objects are the actual houses built from that blueprint.

Class Syntax

Basic Structure:

class ClassName {
private:
    // Private members (only accessible within class)
    
public:
    // Public members (accessible from outside)
    
protected:
    // Protected members (accessible in class and derived classes)
};

Access Specifiers

Control who can access class members:

  • private: Only accessible within the class (default)
  • public: Accessible from anywhere
  • protected: Accessible in class and derived classes

Creating a Simple Class

Example:

class Rectangle {
private:
    double width;
    double height;
    
public:
    // Constructor
    Rectangle(double w, double h) {
        width = w;
        height = h;
    }
    
    // Member functions
    double getArea() {
        return width * height;
    }
    
    double getPerimeter() {
        return 2 * (width + height);
    }
    
    void setDimensions(double w, double h) {
        width = w;
        height = h;
    }
};

Objects

An object is an instance of a class:

Rectangle rect(5.0, 3.0);  // Create object
double area = rect.getArea();  // Call method

Constructors

Constructors initialize objects when they're created.

Default Constructor

No parameters:

class Rectangle {
private:
    double width, height;
    
public:
    Rectangle() {  // Default constructor
        width = 0;
        height = 0;
    }
};

Parameterized Constructor

Takes parameters:

Rectangle(double w, double h) {
    width = w;
    height = h;
}

Constructor Initialization List (Preferred)

More efficient:

Rectangle(double w, double h) : width(w), height(h) {
    // Body can be empty
}

Copy Constructor

Creates object from another object:

Rectangle(const Rectangle& other) {
    width = other.width;
    height = other.height;
}

Destructors

Clean up when object is destroyed:

~Rectangle() {
    // Cleanup code (if needed)
    // Called automatically when object goes out of scope
}

Note: Destructor name starts with ~ and has no parameters.

Member Functions

Functions defined inside a class:

Inside Class Definition

class Rectangle {
public:
    double getArea() {
        return width * height;
    }
};

Outside Class Definition

class Rectangle {
public:
    double getArea();  // Declaration
};

double Rectangle::getArea() {  // Definition
    return width * height;
}

this Pointer

Points to the current object:

class Rectangle {
private:
    double width;
    
public:
    void setWidth(double width) {
        this->width = width;  // this->width refers to member
    }
};

Complete Example

#include <iostream>
#include <string>
using namespace std;

class Student {
private:
    string name;
    int age;
    double gpa;
    
public:
    // Constructor
    Student(string n, int a, double g) : name(n), age(a), gpa(g) {}
    
    // Getter methods
    string getName() const { return name; }
    int getAge() const { return age; }
    double getGpa() const { return gpa; }
    
    // Setter methods
    void setName(string n) { name = n; }
    void setAge(int a) { age = a; }
    void setGpa(double g) { gpa = g; }
    
    // Other methods
    void display() const {
        cout << "Name: " << name << ", Age: " << age 
             << ", GPA: " << gpa << endl;
    }
    
    bool isHonorStudent() const {
        return gpa >= 3.5;
    }
};

int main() {
    Student student1("Alice", 20, 3.8);
    Student student2("Bob", 19, 3.2);
    
    student1.display();
    student2.display();
    
    if (student1.isHonorStudent()) {
        cout << student1.getName() << " is an honor student!" << endl;
    }
    
    return 0;
}

Const Member Functions

Functions that don't modify object state:

double getArea() const {
    return width * height;  // Cannot modify members
}

Benefits:

  • Can be called on const objects
  • Clearly indicates function doesn't modify state
  • Better compiler optimization

Static Members

Belong to the class, not individual objects:

Static Data Member

class Counter {
private:
    static int count;  // Shared by all objects
    
public:
    Counter() { count++; }
    static int getCount() { return count; }
};

int Counter::count = 0;  // Definition outside class

Static Member Function

static int getCount() {
    return count;  // Can only access static members
}

Friend Functions

Functions that can access private members:

class Rectangle {
private:
    double width, height;
    
    friend void printDimensions(Rectangle& r);
};

void printDimensions(Rectangle& r) {
    cout << r.width << " x " << r.height << endl;
}

Operator Overloading

Define how operators work with your class:

class Vector {
private:
    double x, y;
    
public:
    Vector(double x, double y) : x(x), y(y) {}
    
    // Overload + operator
    Vector operator+(const Vector& other) {
        return Vector(x + other.x, y + other.y);
    }
    
    // Overload == operator
    bool operator==(const Vector& other) {
        return (x == other.x && y == other.y);
    }
};

// Usage
Vector v1(1, 2);
Vector v2(3, 4);
Vector v3 = v1 + v2;  // Uses overloaded +

Best Practices

  1. ✅ Use access specifiers appropriately (private by default)
  2. ✅ Provide constructors for initialization
  3. ✅ Use const for member functions that don't modify state
  4. ✅ Use initialization lists in constructors
  5. ✅ Encapsulate data (make data members private)
  6. ✅ Provide getters/setters when needed
  7. ✅ Keep classes focused (single responsibility)
  8. ✅ Use meaningful names for classes and members

Common Mistakes

  • ❌ Forgetting to initialize members
  • ❌ Not using const for getter functions
  • ❌ Making everything public (breaks encapsulation)
  • ❌ Not providing constructors when needed
  • ❌ Forgetting to define static members outside class
  • ❌ Circular dependencies between classes

Next Steps

In future modules, we'll cover:

  • Inheritance: Creating derived classes
  • Polymorphism: Virtual functions and dynamic binding
  • Abstract Classes: Pure virtual functions
  • Templates: Generic programming

Summary

Classes are the foundation of OOP in C++. They allow you to:

  • Organize related data and functions
  • Create reusable code
  • Model real-world entities
  • Implement encapsulation and abstraction

Master classes, and you'll be ready for advanced OOP concepts!

Hands-on Examples

Basic Class Example

#include <iostream>
#include <string>
using namespace std;

class Rectangle {
private:
    double width;
    double height;
    
public:
    // Constructor
    Rectangle(double w, double h) : width(w), height(h) {}
    
    // Getter methods
    double getWidth() const { return width; }
    double getHeight() const { return height; }
    
    // Setter methods
    void setWidth(double w) { width = w; }
    void setHeight(double h) { height = h; }
    
    // Member functions
    double getArea() const {
        return width * height;
    }
    
    double getPerimeter() const {
        return 2 * (width + height);
    }
    
    void display() const {
        cout << "Rectangle: " << width << " x " << height << endl;
        cout << "Area: " << getArea() << endl;
        cout << "Perimeter: " << getPerimeter() << endl;
    }
};

int main() {
    Rectangle rect(5.0, 3.0);
    rect.display();
    
    rect.setWidth(10.0);
    rect.setHeight(6.0);
    cout << "\nAfter modification:" << endl;
    rect.display();
    
    return 0;
}

Classes bundle data (width, height) and functions (getArea, getPerimeter) together. Private members are encapsulated, public methods provide interface. Constructors initialize objects, getters/setters control access.