Oop Notes of Final
Oop Notes of Final
Simple Words: It helps you reuse code and avoid writing the same code again.
class Base {
// base class members
};
private ✅ Yes ❌ No ❌ No
🔸 1. Single Inheritance
class Animal {
public:
void sound() {
cout << "Animal makes sound" << endl;
}
};
class Dog : public Animal {
public:
void bark() {
cout << "Dog barks" << endl;
}
};
✅ Explanation: Dog inherits from Animal. It can use both sound() and bark().
🔸 2. Multilevel Inheritance
Definition: Class inherits from a derived class which is also derived from another
class.
class A {
public:
void showA() {
cout << "Class A" << endl;
}
};
class B : public A {
public:
void showB() {
cout << "Class B" << endl;
}
};
class C : public B {
public:
void showC() {
cout << "Class C" << endl;
}
};
🔸 3. Hierarchical Inheritance
🔸 4. Multiple Inheritance
Definition: One class inherits from more than one base class.
class A {
public:
void funA() {
cout << "Class A" << endl;
}
};
class B {
public:
void funB() {
cout << "Class B" << endl;
}
};
int main() {
D obj;
obj.showA(); // ✅ No ambiguity
}
Suppose we have two classes: Teacher and Student. Both have name, age, and
display() function.
❌ You would need to write the same code twice in both classes.
We create a base class Person and put common data/functions in it. Then, Student
and Teacher inherit from Person.
#include <iostream>
using namespace std;
class Person {
protected:
string name;
int age;
public:
void getDetails() {
cout << "Enter name: ";
cin >> name;
cout << "Enter age: ";
cin >> age;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Student s;
Teacher t;
return 0;
}
🔍 ✅ Explanation:
📝 Summary:
🔹 6.1 Introduction
Inheritance allows one class to inherit the members of another class. It supports
code reusability and helps model real-world relationships. C++ supports several
types of inheritance.
// Base class
class Stack {
protected:
int arr[100], top;
public:
Stack() {
top = -1;
}
void push(int val) {
if (top < 99) {
arr[++top] = val;
}
}
int pop() {
if (top >= 0)
return arr[top--];
else
return -1;
}
};
// Derived class
class EnhancedStack : public Stack {
public:
void display() {
cout << "Stack contents: ";
for (int i = 0; i <= top; i++)
cout << arr[i] << " ";
cout << endl;
}
};
int main() {
EnhancedStack s;
s.push(10);
s.push(20);
s.display();
s.pop();
s.display();
return 0;
}
✅ Explanation:
class B {
public:
void showB() { cout << "Class B" << endl; }
};
class B : public A {
public:
void showB() { cout << "B" << endl; }
};
class C : public B {
public:
void showC() { cout << "C" << endl; }
};
int main() {
D obj;
obj.showA(); // No ambiguity
}
int main() {
Parent *p = new Child();
p->show(); // Output: Child show()
}
✅ Key Points:
class Teacher {
public:
string t_name;
Teacher(string name) : t_name(name) {}
void assignDepartment(Department& dept) {
cout << t_name << " works in " << dept.name << " department.\
n";
}
};
int main() {
Department d("Computer Science");
Teacher t("Khadija");
t.assignDepartment(d);
return 0;
}
✅ Explanation:
✅ Key Points:
class Department {
public:
string dept_name;
vector<Student*> students; // Aggregation
void addStudent(Student* s) {
students.push_back(s);
}
void showStudents() {
cout << dept_name << " Department Students:\n";
for (auto s : students) {
cout << "- " << s->name << endl;
}
}
};
int main() {
Student s1("Ali");
Student s2("Khadija");
cs.showStudents();
return 0;
}
✅ Explanation:
(◊ = aggregation)
🔹 7.5 What is Composition?
Definition:
Composition is a stronger form of Aggregation where one class owns and
manages the lifetime of another class. If the container object is destroyed, so is
the contained object.
✅ Key Points:
class House {
private:
Room bedroom;
Room kitchen;
public:
House() : bedroom("Bedroom"), kitchen("Kitchen") {
cout << "House built.\n";
}
~House() {
cout << "House destroyed.\n";
}
};
int main() {
House h;
return 0;
}
✅ Explanation:
(◆ = composition)
✅ Key Points:
A virtual function is a member function that is declared in the base class and is
overridden in the derived class. It ensures run-time polymorphism.
✅ Syntax:
class Base {
public:
virtual void display() {
cout << "Base class display\n";
}
};
✅ Key Points:
class Animal {
public:
virtual void sound() {
cout << "Animal makes a sound\n";
}
};
int main() {
Animal* a;
Dog d;
a = &d;
✅ Output:
Dog barks
✅ Explanation:
Even though the pointer is of type Animal*, it calls Dog's sound() due to
virtual function and run-time polymorphism.
A pure virtual function is a virtual function with no body in the base class. It
forces derived classes to override the function.
✅ Syntax:
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
};
✅ Key Points:
A class with at least one pure virtual function becomes an Abstract Class.
You cannot create an object of an abstract class.
class Shape {
public:
virtual void draw() = 0; // Pure virtual
};
✅ Output:
Drawing a Circle
✅ Explanation:
🔹 8.10 Summary
Feature Virtual Function Pure Virtual Function
Body in base class Optional ❌ Not allowed
Override in derived Optional ✅ Must override
Object creation Allowed ❌ Not allowed
📘 8. Polymorphism in C++
✅ Key Points:
A virtual function is a member function that is declared in the base class and is overridden in
the derived class. It ensures run-time polymorphism.
✅ Syntax:
class Base {
public:
virtual void display() {
cout << "Base class display\n";
}
};
✅ Key Points:
class Animal {
public:
virtual void sound() {
cout << "Animal makes a sound\n";
}
};
int main() {
Animal* a;
Dog d;
a = &d;
✅ Output:
Dog barks
✅ Explanation:
Even though the pointer is of type Animal*, it calls Dog's sound() due to virtual
function and run-time polymorphism.
A pure virtual function is a virtual function with no body in the base class. It forces derived
classes to override the function.
✅ Syntax:
class Shape {
public:
virtual void draw() = 0; // Pure virtual function
};
✅ Key Points:
A class with at least one pure virtual function becomes an Abstract Class.
You cannot create an object of an abstract class.
class Shape {
public:
virtual void draw() = 0; // Pure virtual
};
int main() {
Shape* s;
Circle c;
s = &c;
s->draw();
return 0;
}
✅ Output:
Drawing a Circle
✅ Explanation:
🔹 8.10 Summary
Feature Virtual Function Pure Virtual Function
Body in base class Optional ❌ Not allowed
Override in derived Optional ✅ Must override
Object creation Allowed ❌ Not allowed
When the function call is resolved at compile time, it's called static binding.
This happens in function overloading or operator overloading.
✅ Example:
#include <iostream>
using namespace std;
class Greet {
public:
void sayHello() {
cout << "Hello! (No name)\n";
}
int main() {
Greet g;
g.sayHello(); // Output: Hello! (No name)
g.sayHello("Khadija"); // Output: Hello, Khadija!
return 0;
}
✅ Explanation:
When the function call is resolved at run-time, it's called dynamic binding.
This happens through virtual functions and function overriding.
✅ Example:
#include <iostream>
using namespace std;
class Vehicle {
public:
virtual void start() {
cout << "Starting vehicle...\n";
}
};
int main() {
Vehicle* v;
Car c;
v = &c;
v->start(); // Output: Starting car engine...
return 0;
}
✅ Explanation:
📊 Comparison Table
Feature Static Binding Dynamic Binding
Timing At compile time At run time
Speed Faster Slightly slower
Flexibility Less flexible More flexible
Achieved By Function/Operator Overloading Virtual Functions
Inheritance Needed ❌ No ✅ Yes
Function Type Normal functions Overridden virtual functions
void category() {
cout << "Animal category\n";
}
};
// Derived class 1
class Dog : public Animal {
public:
void sound() override {
cout << "Dog barks\n";
}
void category() {
cout << "Domestic Animal\n";
}
};
// Derived class 2
class Cat : public Animal {
public:
void sound() override {
cout << "Cat meows\n";
}
void category() {
cout << "Pet Animal\n";
}
};
int main() {
Animal* a;
Dog d;
Cat c;
// Runtime Polymorphism
a = &d;
a->sound(); // Output: Dog barks
a->category(); // Output: Animal category (not overridden
because not virtual)
a = &c;
a->sound(); // Output: Cat meows
a->category(); // Output: Animal category
return 0;
}
✅ Explanation of Above Program:
Line Behavior Type
a->sound() Calls derived class version Dynamic Binding
a->category() Calls base class version Static Binding
✅ Final Summary
Concept Main Point
Static Binding Compile-time decision using overloading
Dynamic Binding Run-time decision using overriding & virtual functions
Programming Use Improves flexibility and reusability
Polymorphism Type Compile-time and Run-time
In C++, file handling is done through a library called <fstream>, which provides
tools to create, read, write, and update files.
✅ Diagram:
ios
|
---------------------
| | |
ifstream ofstream fstream
ios::binary
Opens the file in binary mode (instead of text
mode)
You can combine these modes using the bitwise OR | operator.
Example:
fstream file("data.txt", ios::in | ios::out);
int main() {
ofstream outFile("example.txt"); // Open file in
write mode
outFile << "Hello, Khadija!\n"; // Write to file
outFile.close(); // Close the file
string line;
ifstream inFile("example.txt"); // Open file in
read mode
while (getline(inFile, line)) {
cout << line << endl; // Display
contents
}
inFile.close(); // Close the file
return 0;
}
✅ Explanation:
ofstream is used to create/write the file.
ifstream is used to read the file.
getline() reads one line at a time.
File must always be closed using .close() after use.
✅ Summary Table
Feature Use
ifstream Read data from file
Feature Use
ofstream Write data to file
fstream Read and write
File Modes Control how file is opened
close() Closes the file
getline() Reads a line from file
Class Use
ofstream Write to a text file
ifstream Read from a text file
fstream Read and write to file
int main() {
ofstream outFile("data.txt"); // Open file for writing
✅ Explanation:
int main() {
ifstream inFile("data.txt"); // Open file for reading
string line;
return 0;
}
✅ Explanation:
✅ Summary Table
Task Class Description
Write to text file ofstream Sends data to a file
Read from file ifstream Reads data from a file
Both read & write fstream Dual-purpose file handling
Store as plain text Text filing Human-readable storage format
int main() {
int a = 10, b = 0;
try {
if (b == 0)
throw "Division by zero error!";
cout << "Result: " << a / b << endl;
}
catch (const char* msg) {
cout << "Exception Caught: " << msg << endl;
}
✅ Explanation: