The object-oriented approach is a programming paradigm based on the concept of objects, which can contain data and methods. This approach promotes modularity, code reusability, and scalability.
Example:
Consider a class "Car" with attributes like color, model, and methods like start() and stop().
Object-oriented programming (OOP) differs significantly from other paradigms:
Example:
Functional: A function add(a, b) returns a + b.
OOP: A class Calculator with method add(a, b) implements addition.
Example:
Class Vehicle: Attributes (speed, color), Method (move()).
Class Car inherits Vehicle and adds Method (openSunroof()).
The C language is a procedural programming language. Object-oriented programming builds upon the foundations of procedural paradigms but organizes code into objects.
Example:
C:
void add(int a, int b) { return a + b; }
C++:
class Calculator {
public: int add(int a, int b) { return a + b; }
};
C++ enhances C with object-oriented features such as:
Example:
C:
int* p = (int*) malloc(sizeof(int));
C++:
int* p = new int;
// Deleting dynamically allocated memory
C: free(p);
C++: delete p;
Encapsulation is the bundling of data and methods that operate on the data within a class. It ensures information hiding by restricting access to certain components of an object using access specifiers (private, protected, public).
Example:
class Car {
private:
string color;
public:
void setColor(string c) { color = c; }
string getColor() { return color; }
};
Abstract Data Types (ADTs) define a data structure and the operations that can be performed on it, without specifying implementation details.
Example:
ADT Stack:
Operations: push(), pop(), peek().
Implementation: Array or Linked List.
An object is an instance of a class. A class is a blueprint that defines attributes (data) and methods (functions).
Example:
class Person {
string name;
int age;
void display() { cout << "Name: " << name << ", Age: " << age; }
};
Person p1; // Object of class Person.
State: Defined by the attributes of an object.
Identity: Unique property to distinguish objects.
Behavior: Defined by the methods of the object.
Example:
Object: Car
State: color = "red", speed = 100
Identity: Unique memory address
Behavior: start(), stop(), accelerate()
Constructors are special methods called when an object is created. Destructors are called when an object is destroyed, ensuring resource cleanup.
Example:
class Car {
Car() { cout << "Car created"; } // Constructor
~Car() { cout << "Car destroyed"; } // Destructor
};
In C++, functions can have default parameter values, which are used if no argument is provided during the function call.
Example:
void greet(string name = "Guest") {
cout << "Hello, " << name;
}
greet(); // Output: Hello, Guest
greet("Alice"); // Output: Hello, Alice
In C++, objects can be classified into various types such as local objects (within a function) and global objects (accessible throughout the program).
Example:
Local Object:
void func() { Person p1; }
Global Object:
Person p2;
C++ does not have automatic garbage collection like some other languages. Instead, it uses dynamic memory allocation with operators like new and delete.
Example:
int* p = new int(10); // Dynamic allocation
delete p; // Memory deallocation
An abstract class is a class that cannot be instantiated and serves as a blueprint for derived classes. It may contain pure virtual functions.
Example:
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
};
class Circle : public Shape {
void draw() { cout << "Drawing Circle"; }
};
Inheritance allows a class (derived class) to inherit attributes and methods from another class (base class). This promotes code reuse and a hierarchical structure in the program.
Example:
class Vehicle {
public:
int speed;
void move() { cout << "Vehicle moving"; }
};
class Car : public Vehicle {
public:
void openSunroof() { cout << "Sunroof opened"; }
};
Car c;
c.move(); // Inherited from Vehicle
A class hierarchy organizes classes in a tree-like structure with the base class at the top and derived classes branching below.
Example:
Base Class: Shape
Derived Classes: Circle, Rectangle, Triangle
Sub-derived Class: EquilateralTriangle (from Triangle)
C++ supports three types of class derivation:
Example:
class Base {
public: int x;
};
class Derived : public Base {};
// x remains public in Derived
Aggregation: Represents a "has-a" relationship where the lifetime of the contained objects is independent of the container.
Composition: Represents a "part-of" relationship where the contained objects' lifetime depends on the container.
Example:
Aggregation:
class Engine {};
class Car {
Engine* engine; // Engine can exist without Car
};
Composition:
class Car {
Engine engine; // Engine is part of Car
};
Polymorphism allows objects of different types to be treated as objects of a common base type. It enables flexibility and extensibility in programs.
Example:
class Shape {
public: virtual void draw() { cout << "Drawing Shape"; }
};
class Circle : public Shape {
public: void draw() { cout << "Drawing Circle"; }
};
Shape* s = new Circle();
s->draw(); // Output: Drawing Circle
Polymorphism can be categorized into:
Method polymorphism refers to multiple methods with the same name but different parameter lists.
Example:
class Calculator {
public:
int add(int a, int b) { return a + b; }
float add(float a, float b) { return a + b; }
};
Calculator c;
c.add(3, 4); // Calls int add
c.add(3.5f, 4.5f); // Calls float add
This technique involves using generic programming, such as templates, to implement polymorphism.
Example:
template
class Box {
T value;
public:
void setValue(T v) { value = v; }
T getValue() { return value; }
};
Box intBox;
intBox.setValue(10);
Operator overloading allows operators to be redefined for user-defined types.
Example:
class Complex {
int real, imag;
public:
Complex operator+(const Complex& c) {
return Complex(real + c.real, imag + c.imag);
}
};
Parametric polymorphism is achieved using templates, allowing code to operate on various types without modification.
Example:
template
T add(T a, T b) {
return a + b;
}
int x = add(2, 3);
float y = add(2.5, 3.5);
A template function allows the definition of functions that can work with any data type. This makes code more reusable and type-safe.
Example:
template
T max(T a, T b) {
return (a > b) ? a : b;
}
int x = max(10, 20); // Works with integers
float y = max(10.5, 20.3); // Works with floats
Function name overloading is the ability to define multiple functions with the same name but with different parameter lists in the same scope.
Example:
class Calculator {
public:
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
};
Calculator c;
c.add(3, 5); // Calls int add
c.add(3.5, 4.5); // Calls double add
Method overriding occurs when a derived class redefines a method from the base class to provide specific functionality.
Example:
class Base {
public:
virtual void display() { cout << "Base display"; }
};
class Derived : public Base {
public:
void display() override { cout << "Derived display"; }
};
Base* obj = new Derived();
obj->display(); // Output: Derived display
Run-time polymorphism is achieved through inheritance and virtual functions. The decision of which method to execute is made at runtime.
Example:
class Shape {
public:
virtual void draw() { cout << "Drawing Shape"; }
};
class Circle : public Shape {
public:
void draw() override { cout << "Drawing Circle"; }
};
Shape* s = new Circle();
s->draw(); // Output: Drawing Circle
Multiple inheritance allows a class to inherit from more than one base class. This can lead to complexities like the diamond problem, which is managed using virtual inheritance.
Example:
class A {
public: void showA() { cout << "A"; }
};
class B {
public: void showB() { cout << "B"; }
};
class C : public A, public B {};
C obj;
obj.showA(); // Output: A
obj.showB(); // Output: B
In C++, streams are used for input and output operations, while files allow storing and retrieving data permanently. The fstream library provides functionalities for file handling.
Example:
#include
using namespace std;
ofstream outFile("example.txt");
outFile << "Hello, World!"; // Write to file
outFile.close();
ifstream inFile("example.txt");
string content;
inFile >> content; // Read from file
cout << content;
A namespace is a declarative region that provides a scope to the identifiers (functions, variables, etc.) to avoid name conflicts. The standard namespace in C++ is std.
Example:
namespace MyNamespace {
int x = 10;
void display() { cout << "Namespace Example"; }
}
using namespace MyNamespace;
display(); // Output: Namespace Example
Exception handling in C++ is used to manage runtime errors gracefully. The keywords try, catch, and throw are used to implement it.
Example:
try {
int a = 10, b = 0;
if (b == 0) throw "Division by zero!";
cout << a / b;
} catch (const char* msg) {
cout << "Error: " << msg;
}
Generic classes in C++ are implemented using templates to enable the creation of classes that can work with any data type.
Example:
template
class Box {
T value;
public:
void setValue(T v) { value = v; }
T getValue() { return value; }
};
Box intBox;
intBox.setValue(5);
cout << intBox.getValue(); // Output: 5