Module 8: Object-Oriented Programming (Classes)
Chapter 8 • Intermediate
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
- ✅ Use access specifiers appropriately (private by default)
- ✅ Provide constructors for initialization
- ✅ Use const for member functions that don't modify state
- ✅ Use initialization lists in constructors
- ✅ Encapsulate data (make data members private)
- ✅ Provide getters/setters when needed
- ✅ Keep classes focused (single responsibility)
- ✅ 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.
Practice with Programs
Reinforce your learning with hands-on practice programs
Related Program Topics
Recommended Programs
Hello World
BeginnerThe classic first program that prints "Hello World" to the console
Display Your Name
BeginnerProgram to display your name on the screen
User Input
BeginnerProgram to take input from user and display it
Array Max & Min
BeginnerProgram to find maximum and minimum element in an array
Array Average
BeginnerProgram to calculate average of array elements