0% found this document useful (0 votes)
3 views29 pages

OOP Inheritance Notes

The document provides a comprehensive overview of inheritance in C++, a key concept in Object-Oriented Programming. It explains the 'is-a' relationship, access control, constructor order, and the use of protected members, along with practical examples and syntax. Key rules and common pitfalls related to inheritance are also highlighted for clarity.

Uploaded by

bakarali1167
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views29 pages

OOP Inheritance Notes

The document provides a comprehensive overview of inheritance in C++, a key concept in Object-Oriented Programming. It explains the 'is-a' relationship, access control, constructor order, and the use of protected members, along with practical examples and syntax. Key rules and common pitfalls related to inheritance are also highlighted for clarity.

Uploaded by

bakarali1167
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

OOP C++

Inheritance
is-a Relationship, Access Control & Constructor Order
27-April-2026
SECTION 1 : WHAT IS INHERITANCE?
Inheritance is one of the four fundamental pillars of Object-Oriented Programming. It implements the 'is-
a' relationship between classes. When one class inherits from another, it means the derived class IS A
type of the base class.
Inheritance allows a class to reuse, extend, and modify the behavior that is defined in another class.
The class whose properties are inherited is called the Base Class (Parent Class), and the class that
inherits is called the Derived Class (Child Class).

1.1 The is-a Relationship


The 'is-a' relationship is the foundation of inheritance. Before using inheritance in code, always ask
yourself: Does the derived class IS-A type of the base class? If yes — inheritance is correct.
Real-World Example Explanation
Rectangle is a Shape Shape is base (parent), Rectangle is derived (child)
Car is a Vehicle Vehicle is base, Car is derived
Student is a Person Person is base, Student is derived
Teacher is a Person Person is base, Teacher is derived
Dog is an Animal Animal is base, Dog is derived
Square is a Rectangle Rectangle is base, Square is derived

Teacher has some extra properties (like subject, employee ID), but she also has the same properties
as Person (name, age, gender). This is the essence of inheritance — the derived class gets all base
class properties PLUS adds its own unique properties.

⚡ KEY RULE — is-a vs has-a


is-a → Inheritance → class Dog : public Animal { }
has-a (strong) → Composition → A obj; inside class
has-a (weak) → Aggregation → A* obj; pointer

ONLY Inheritance = is-a. Composition and Aggregation are has-a.


If you can say 'X IS A Y', use inheritance. If 'X HAS A Y', use composition/aggregation.

1.2 UML Diagram for Inheritance


In UML, inheritance is shown with an open arrowhead (hollow triangle) pointing from child to parent:
📄 UML_inheritance.txt

+──────────────+
│ Vehicle │ ← Base / Parent class
+──────────────+
▲ ← Open arrowhead (inheritance)

+──────────────+
│ Car │ ← Derived / Child class
+──────────────+

Another example:
Person
/ \
Teacher Student ← Both inherit from Person
SECTION 2 : SYNTAX OF INHERITANCE IN C++
2.1 Basic Syntax
The syntax for declaring a derived class in C++ is:
📄 [Link]

// Base class definition


class A {
public:
// public members
private:
// private members
};

// Derived class — B inherits publicly from A


class B : public A {
public:
// B's own members + everything inherited from A
};

📌 Syntax Breakdown
class B → Name of the derived (child) class
: public A → B inherits from A using public inheritance
The keyword after ':' is the access specifier for inheritance
Most common: public inheritance (as taught in class)

2.2 First Complete Inheritance Program


This is the most basic inheritance program. Class A is the base (parent). Class B is derived (child) from
A. An object of B can call functions of both A and B.
📄 basic_inheritance.cpp

#include <iostream>
using namespace std;

class A { // Base / Parent class


public:
void g() { // public function of A
cout << "Function g() from class A" << endl;
}
private:
// private members of A — NOT accessible in B
};

class B : public A { // B is derived from A (is-a relationship)


public:
void f() { // B's own function
cout << "Function f() from class B" << endl;
}
};

int main() {
B obj; // object of derived class
obj.g(); // calls A's function — inherited!
obj.f(); // calls B's own function
return 0;
}

✅ Expected Output
Function g() from class A
Function f() from class B

📌 Key Observation
obj is of type B (derived class).
obj.g() works even though g() is defined in A — because B inherits all public members of A.
obj.f() calls B's own function.
One object (obj) can access functions from BOTH classes.
SECTION 3 : ACCESS CONTROL IN INHERITANCE
3.1 The Three Access Modifiers
C++ has three access modifiers: public, private, and protected. Understanding which members get
inherited and which don't is critical for exams.
Modifier Meaning Where Accessible Example

public Accessible everywhere In same class, derived int x = 5; // public


class, main()

private Accessible only in SAME NOT in derived class, int x = 5; // private


class NOT in main()

protected Like private but ALSO in In same class + derived protected: int x;
derived classes class, NOT in main()

3.2 private vs protected — The Key Difference


This is one of the most important concepts for the exam. The difference between private and protected
only matters when inheritance is involved.
📄 private_vs_protected.cpp

#include <iostream>
using namespace std;

class A {
private:
int priv_var = 10; // ❌ CANNOT be accessed in B
protected:
int prot_var = 20; // ✅ CAN be accessed in B (derived)
public:
int pub_var = 30; // ✅ CAN be accessed everywhere

void pub_func() {
cout << "Public function of A" << endl;
}
int get_priv() { return priv_var; } // getter for private
};

class B : public A {
public:
void show() {
// cout << priv_var; // ❌ ERROR: private in A — not accessible
cout << prot_var; // ✅ protected — accessible in derived class
cout << pub_var; // ✅ public — always accessible
cout << get_priv(); // ✅ access private via getter function
}
};

int main() {
A a;
B obj;
[Link](); // works
// obj.prot_var; // ❌ ERROR: protected — NOT in main()
// obj.priv_var; // ❌ ERROR: private — NOT in main()
obj.pub_var = 50; // ✅ public — accessible in main()
obj.pub_func(); // ✅ public function accessible in main()
a.get_priv(); // ✅ public getter
return 0;
}

✅ Expected Output
20
30
10
Public function of A

⚠️Access Summary — Exam Trap


private → Own class ONLY. Not in derived class. Not in main().
protected → Own class + Derived class. NOT in main().
public → Everywhere: own class, derived class, main().

If you inherit with 'public', public stays public and protected stays protected.
private members are NEVER inherited — they exist but can't be accessed directly.

3.3 Accessing Private Members via Getters and Setters


Private members of the base class cannot be accessed directly in the derived class OR in main().
However, you can access them through public getter/setter functions. This is a key point from your
class notes.
📄 getter_setter_inheritance.cpp

#include <iostream>
using namespace std;

class A {
private:
int secret = 42; // private — hidden from everyone
public:
int getSecret() { return secret; } // getter
void setSecret(int s) { secret = s; } // setter
};

class B : public A {
public:
void display() {
// cout << secret; // ❌ ERROR! Direct access to private
cout << getSecret(); // ✅ Access via getter — WORKS!
}
};

int main() {
B obj;
[Link](100); // set via setter
[Link](); // reads via getter inside B
cout << [Link](); // read via getter from main()
return 0;
}

✅ Expected Output
100
100
SECTION 4 : CONSTRUCTORS & DESTRUCTORS IN INHERITANCE
4.1 Order of Constructors
This is one of the most commonly tested topics in OOP exams. The constructor order in inheritance
follows the same FIFO (First In, First Out) rule — the BASE class constructor always runs FIRST, then
the DERIVED class constructor runs.
Concept Rule
Constructor Order Base class (A) FIRST → then Derived class (B)
Destructor Order Derived class (B) FIRST → then Base class (A)
Why? Base must be ready before derived can build on it
Destructor Why? LIFO — derived is dismantled before its foundation (base)
Same as? Same order as Composition — inner first, outer last

📄 constructor_order.cpp

#include <iostream>
using namespace std;

class A { // Base class


public:
A() {
cout << "A Constructor called" << endl;
}
~A() {
cout << "A Destructor called" << endl;
}
};

class B : public A { // Derived class


public:
B() {
cout << "B Constructor called" << endl;
}
~B() {
cout << "B Destructor called" << endl;
}
};

int main() {
B obj; // Object of derived class created
return 0; // obj goes out of scope — destruction begins
}

✅ Expected Output
A Constructor called
B Constructor called
B Destructor called
A Destructor called
⚡ Constructor / Destructor Order — Exam Trap
Constructor: Base (A) runs FIRST → Derived (B) runs SECOND
Destructor: Derived (B) runs FIRST → Base (A) runs LAST

This is LIFO (Last In, First Out) for destructors.


Same rule applies in Composition (inner first, outer last).
This is THE most common output question in exams!

4.2 Private Constructor — Error Case


If the base class constructor is private, it CANNOT be called by the derived class. This causes a
compilation error. As noted in your class notes: 'If constructor is private then error.'
📄 private_constructor_error.cpp

#include <iostream>
using namespace std;

class A {
private: // ← Constructor is PRIVATE
A() { // ❌ Cannot be called from B!
cout << "A Constructor" << endl;
}
public:
void show() { cout << "A show()" << endl; }
};

class B : public A { // ❌ ERROR during compilation!


public:
B() { // Tries to call A() — but A() is private!
cout << "B Constructor" << endl;
}
};

// int main() { B obj; } // This would FAIL to compile


// Error: 'A::A()' is private

⚠️Private Constructor Rule


If the base class constructor is private, derived class CANNOT be created.
The compiler automatically tries to call the base constructor — if private, it fails.
Fix: Make the constructor public or protected.
Protected constructor: only allows creation by derived class, not from main().

4.3 Parameterized Constructors in Inheritance


When the base class has a parameterized constructor (no default constructor), the derived class MUST
pass the required arguments to the base class using the member initializer list. As your notes say:
'parameterized constructors in child class will always be written in member initializer list of parent class.'
📄 parameterized_constructor_inheritance.cpp
#include <iostream>
#include <string>
using namespace std;

class Person { // Base class


private:
string name;
int age;
public:
Person(string n, int a) : name(n), age(a) { // Parameterized ONLY
cout << "Person Constructor: " << name << endl;
}
void showPerson() {
cout << "Name: " << name << ", Age: " << age << endl;
}
~Person() {
cout << "Person Destructor: " << name << endl;
}
};

class Student : public Person { // Derived class


private:
int rollNo;
public:
// Must pass args to Person via initializer list
Student(string n, int a, int r) : Person(n, a), rollNo(r) {
cout << "Student Constructor, Roll: " << rollNo << endl;
}
void showStudent() {
showPerson(); // call base class function
cout << "Roll No: " << rollNo << endl;
}
~Student() {
cout << "Student Destructor" << endl;
}
};

int main() {
Student s("Ali", 20, 101);
[Link]();
return 0;
}

✅ Expected Output
Person Constructor: Ali
Student Constructor, Roll: 101
Name: Ali, Age: 20
Roll No: 101
Student Destructor
Person Destructor: Ali
SECTION 5 : PROTECTED ACCESS MODIFIER
Protected is a keyword that acts as an access modifier — just like public and private. Your class notes
describe it as: 'Access modifier like public & private. Is accessible in itself class as well as in derived
class but not in main.'

5.1 What is protected?


Protected members are like a middle ground between public and private. They are visible inside the
class itself AND inside any derived class, but they are NOT visible in main() or any other outside
function.
📄 protected_demo.cpp

#include <iostream>
using namespace std;

class A {
protected:
void g() { // protected function
cout << "Protected g() in A" << endl;
}
private:
int secret = 99;
public:
int pub_data = 10;
};

class B : public A {
public:
void show() {
g(); // ✅ allowed — protected accessible in derived
// cout << secret; // ❌ ERROR — private not accessible
cout << pub_data; // ✅ public — accessible
}
};

int main() {
A a;
B obj;

[Link](); // ✅ works
// obj.g(); // ❌ ERROR — protected NOT in main()
// a.g(); // ❌ ERROR — protected NOT in main()
obj.pub_data = 20; // ✅ public — accessible in main()
return 0;
}

✅ Expected Output
Protected g() in A
10
5.2 Access Through Objects in main()
Your class notes explicitly show the following access diagram. This is critical — the access specifier
determines whether you can call through an object from main():
📄 access_diagram.cpp

// Based on class notes:

class A {
protected: g(); // protected
};

class B : public A {
public: f(); // B's own function
};

int main() {
A a;
B obj;

obj.g(); // ❌ NOT allowed — g() is protected in A


obj.f(); // ✅ allowed — f() is public in B
a.g(); // ❌ NOT allowed — g() is protected in A
}

📌 Protected Access Rule — 3 Steps


STEP 1: Is the member public? → Accessible EVERYWHERE (derived, main)
STEP 2: Is the member protected? → Accessible in own class + derived class ONLY
STEP 3: Is the member private? → Accessible in own class ONLY

When you call via '[Link]()' from main() — only PUBLIC members work.
Protected and private are NEVER accessible via object in main().
SECTION 6 : COMPLETE PERSON-STUDENT-TEACHER EXAMPLE
This is the classic example from your handwritten notes. Person is the base class. Both Student and
Teacher inherit from Person — they 'is-a' Person.
📄 person_student_teacher.cpp

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

// ─── BASE CLASS ──────────────────────────────


class Person {
protected: // protected so derived classes can access
string name;
int age;
public:
Person(string n, int a) : name(n), age(a) {
cout << "Person Constructor: " << name << endl;
}
void showPerson() {
cout << "Name: " << name << ", Age: " << age << endl;
}
~Person() {
cout << "Person Destructor: " << name << endl;
}
};

// ─── DERIVED CLASS 1: Student ─────────────────


class Student : public Person {
private:
int rollNo;
string major;
public:
Student(string n, int a, int r, string m)
: Person(n, a), rollNo(r), major(m) { // base init in list
cout << "Student Constructor" << endl;
}
void showStudent() {
showPerson(); // inherited from Person
cout << "Roll No: " << rollNo
<< ", Major: " << major << endl;
}
~Student() {
cout << "Student Destructor" << endl;
}
};

// ─── DERIVED CLASS 2: Teacher ─────────────────


class Teacher : public Person {
private:
string subject;
int empID;
public:
Teacher(string n, int a, string s, int id)
: Person(n, a), subject(s), empID(id) {
cout << "Teacher Constructor" << endl;
}
void showTeacher() {
showPerson(); // inherited from Person
cout << "Subject: " << subject
<< ", EmpID: " << empID << endl;
}
~Teacher() {
cout << "Teacher Destructor" << endl;
}
};

int main() {
cout << "--- Creating Student ---" << endl;
Student s("Abu Bakar", 20, 101, "Data Science");
[Link]();

cout << endl << "--- Creating Teacher ---" << endl;
Teacher t("Dr. Tariq", 45, "OOP", 5001);
[Link]();

return 0;
}

✅ Expected Output
--- Creating Student ---
Person Constructor: Abu Bakar
Student Constructor
Name: Abu Bakar, Age: 20
Roll No: 101, Major: Data Science

--- Creating Teacher ---


Person Constructor: Dr. Tariq
Teacher Constructor
Name: Dr. Tariq, Age: 45
Subject: OOP, EmpID: 5001
Teacher Destructor
Person Destructor: Dr. Tariq
Student Destructor
Person Destructor: Abu Bakar

📌 Key Observations
Both Student and Teacher share Person's properties (name, age) via inheritance.
Each derived class adds its OWN unique properties.
Destructor order: Derived first, then Base (LIFO).
Person's constructor runs BEFORE Student's or Teacher's constructor.
Both classes call showPerson() — they REUSE the base class function.
SECTION 7 : COMPOSITION vs INHERITANCE
Your class notes have an important comparison: 'Friend vs Composition vs Inheritance'. Understanding
the difference is essential. The key behavioral difference is HOW the public of the parent is accessed.

7.1 Access Difference


Relationship How parent's public is accessible
Composition Can only access the public of parent class IN THE DERIVED
CLASS, not in main().
Inheritance Can access the public of parent class IN THE DERIVED CLASS
AND ALSO in main().

📄 composition_vs_inheritance.cpp

#include <iostream>
using namespace std;

class A {
public:
void g() { cout << "A's g()" << endl; }
void f() { cout << "A's f()" << endl; }
};

// ─── COMPOSITION ─────────────────────────────


class C_Composition {
private:
A obj; // A object inside C (composition)
public:
void callG() { // wrapper — only way to reach A.g from outside
obj.g(); // ✅ can call A's public inside C
}
};

// ─── INHERITANCE ─────────────────────────────


class C_Inheritance : public A { // inherits from A
public:
// g() and f() are directly inherited — no wrapper needed
};

int main() {
C_Composition comp;
[Link](); // ✅ only through wrapper
// [Link].g(); // ❌ obj is private, can't reach from main

C_Inheritance inh;
inh.g(); // ✅ directly accessible — inherited as public
inh.f(); // ✅ directly accessible — inherited as public
return 0;
}

✅ Expected Output
A's g()
A's g()
A's f()

7.2 Complete Comparison Table


Relationship Keyword Syntax Access Pattern

Inheritance is-a class B : public A obj.g() directly in main()

Composition has-a (strong) A obj; inside class Only through wrapper in


derived

Aggregation has-a (weak) A* obj; pointer Only through wrapper in


derived
SECTION 8 : COPY CONSTRUCTOR & ASSIGNMENT IN INHERITANCE
8.1 Copy Constructor in Inheritance
From your class notes: The copy constructor of a derived class must also copy the base class part.
When you copy a derived object, you need to copy both the base part and the derived part. The base
class copy constructor is called through the initializer list.
📄 copy_constructor_inheritance.cpp

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

class A {
protected:
string name;
public:
A(string n) : name(n) {
cout << "A Parameterized Constructor" << endl;
}
A(const A& obj) : name([Link]) { // Copy constructor of A
cout << "A Copy Constructor" << endl;
}
void print() { cout << "Name: " << name << endl; }
};

class B : public A {
private:
int id;
public:
B(string n, int i) : A(n), id(i) {
cout << "B Parameterized Constructor" << endl;
}
// Copy constructor of B — must copy A part too
B(const B& obj) : A(obj), id([Link]) { // A(obj) calls A's copy ctor
cout << "B Copy Constructor" << endl;
}
void print() {
A::print(); // call base class version
cout << "ID: " << id << endl;
}
};

int main() {
B b1("BakarCode", 42); // parameterized
B b2(b1); // copy constructor
[Link]();
return 0;
}

✅ Expected Output
A Parameterized Constructor
B Parameterized Constructor
A Copy Constructor
B Copy Constructor
Name: BakarCode
ID: 42

8.2 Assignment Operator in Inheritance


From class notes: 'in assignment operator in inheritance: oa = obj is valid. oa only accesses object part,
not by any means. There is inheritance.' The default assignment operator copies only the derived
class's own members.
📄 assignment_in_inheritance.cpp

#include <iostream>
using namespace std;

class A {
protected:
int x;
public:
A(int v) : x(v) {}
void print() { cout << "A::x = " << x << endl; }
};

class B : public A {
private:
int y;
public:
B(int a, int b) : A(a), y(b) {}
void print() {
A::print(); // prints base part
cout << "B::y = " << y << endl;
}
};

int main() {
B ob1(10, 20);
B ob2(0, 0);

ob2 = ob1; // default assignment operator


[Link](); // both x and y are copied

// A oa;
// oa = ob1; // ❌ Slicing — only A part copied, B part lost
return 0;
}

✅ Expected Output
A::x = 10
B::y = 20
SECTION 9 : FUNCTION OVERRIDING IN INHERITANCE
When a derived class defines a function with the same name and signature as a base class function,
this is called Function Overriding. The derived class 'overrides' (replaces) the base class version.

9.1 Basic Function Overriding


📄 function_overriding.cpp

#include <iostream>
using namespace std;

class A {
public:
void print() {
cout << "print() from class A (Base)" << endl;
}
};

class B : public A {
public:
void print() { // OVERRIDES A's print()
cout << "print() from class B (Derived)" << endl;
}
};

int main() {
B obj;
[Link](); // calls B's version (overrides A's)

// To call A's version explicitly:


obj.A::print(); // use scope resolution operator
return 0;
}

✅ Expected Output
print() from class B (Derived)
print() from class A (Base)

9.2 Calling Base Class Print from Derived — A::Print()


From your class notes: 'when we write Print() { A::Print(); }'. This is a very common pattern — the
derived class overrides a function, but calls the base version first (or after) to reuse its logic.
📄 base_class_name_scope.cpp

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

class A {
protected:
string baseData = "I am from A";
public:
void print() {
cout << "A::print() — " << baseData << endl;
}
};

class B : public A {
private:
string derivedData = "I am from B";
public:
void print() { // overrides A::print
A::print(); // explicitly call base version FIRST
cout << "B::print() — " << derivedData << endl;
}
};

int main() {
B obj;
[Link](); // calls B's version, which calls A's
obj.A::print(); // call A's version directly
return 0;
}

✅ Expected Output
A::print() — I am from A
B::print() — I am from B
A::print() — I am from A
SECTION 10 : STATIC MEMBERS IN INHERITANCE
Your class notes state: 'static data members or functions are also accessible by derived class in main.'
Static members belong to the class itself (not to any specific object), so they are shared across all
instances — including those of derived classes.
📄 static_in_inheritance.cpp

#include <iostream>
using namespace std;

class A {
public:
static int count; // static member — shared by all
static void showCount() {
cout << "Count = " << count << endl;
}
A() { count++; } // increment on each object creation
};

int A::count = 0; // define static outside class

class B : public A {
public:
B() { count++; } // B also increments A's static count
};

int main() {
A a1, a2;
B b1, b2, b3;

A::showCount(); // ✅ call via class name


B::showCount(); // ✅ derived class can also call static
[Link](); // ✅ call via derived object
cout << A::count; // ✅ direct access to static via class
cout << B::count; // ✅ same static — same value!
return 0;
}

✅ Expected Output
Count = 10
Count = 10
Count = 10
10
10

📌 Static Members in Inheritance


Static members are NOT per-object — they belong to the class itself.
Derived classes share the SAME static member as the base class.
Can be accessed via: ClassName::member, DerivedName::member, or [Link].
Static members ARE accessible in derived class AND in main().
Empty Class Size Rule
From your class notes: 'If a class has no data members then by default it's value is size = 1.' This is a
C++ rule — the compiler gives every object at least 1 byte of storage so it has a unique address.
📄 empty_class_size.cpp

#include <iostream>
using namespace std;

class A { // has data members


public:
int x; // 4 bytes
};

class B { // empty class — no data members


public:
void show() {} // functions don't count
};

int main() {
cout << sizeof(A) << endl; // 4 (has int x)
cout << sizeof(B) << endl; // 1 (empty class minimum size)
return 0;
}

✅ Expected Output
4
1
SECTION 11 : VEHICLE & CAR EXAMPLE
A complete real-world style program demonstrating inheritance with Vehicle as base and Car as
derived — the example used in your class notes UML diagram.
📄 vehicle_car_inheritance.cpp

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

// ─── BASE CLASS: Vehicle ───────────────────


class Vehicle {
protected:
string brand;
int year;
int speed;
public:
Vehicle(string b, int y, int s) : brand(b), year(y), speed(s) {
cout << "Vehicle Constructor: " << brand << endl;
}
void move() {
cout << brand << " is moving at " << speed << " km/h" << endl;
}
void showInfo() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
~Vehicle() {
cout << "Vehicle Destructor: " << brand << endl;
}
};

// ─── DERIVED CLASS: Car ────────────────────


class Car : public Vehicle {
private:
int doors;
string fuelType;
public:
Car(string b, int y, int s, int d, string f)
: Vehicle(b, y, s), doors(d), fuelType(f) {
cout << "Car Constructor: " << brand << endl;
}
void showCar() {
showInfo(); // inherited from Vehicle
cout << "Doors: " << doors
<< ", Fuel: " << fuelType << endl;
}
~Car() {
cout << "Car Destructor: " << brand << endl;
}
};

int main() {
Car c1("Toyota", 2024, 180, 4, "Petrol");
[Link](); // inherited from Vehicle
[Link](); // Car's own function
return 0;
}

✅ Expected Output
Vehicle Constructor: Toyota
Car Constructor: Toyota
Toyota is moving at 180 km/h
Brand: Toyota, Year: 2024
Doors: 4, Fuel: Petrol
Car Destructor: Toyota
Vehicle Destructor: Toyota
SECTION 12 : POINT & POINT3D EXAMPLE
From your class notes — a Point class (base) and a Point3D class (derived) that extends Point with a
z-coordinate. Also demonstrates the use of 'protected' so derived can access x and y, and the friend <<
operator.
📄 point_point3d.cpp

#include <iostream>
using namespace std;

// ─── BASE CLASS: Point (2D) ─────────────────


class Point {
protected: // protected so Point3D can access x, y
int x, y;
public:
Point(int x, int y) : x(x), y(y) {
cout << "Point Constructor (" << x << "," << y << ")" << endl;
}
friend ostream& operator<< (ostream& out, const Point& p) {
out << "(" << p.x << ", " << p.y << ")";
return out;
}
~Point() {
cout << "Point Destructor" << endl;
}
};

// ─── DERIVED CLASS: Point3D ─────────────────


class Point3D : public Point {
private:
int z;
public:
Point3D(int x, int y, int z) : Point(x, y), z(z) {
cout << "Point3D Constructor (" << x << "," << y << "," << z << ")" << endl;
}
friend ostream& operator<< (ostream& out, const Point3D& p) {
out << "(" << p.x << ", " << p.y << ", " << p.z << ")";
return out;
}
~Point3D() {
cout << "Point3D Destructor" << endl;
}
};

int main() {
Point3D p3d(1, 5, 7);
cout << "3D Point: " << p3d << endl;
return 0;
}

✅ Expected Output
Point Constructor (1,5)
Point3D Constructor (1,5,7)
3D Point: (1, 5, 7)
Point3D Destructor
Point Destructor
📌 Why protected for x, y?
If x and y were private, Point3D could NOT access them directly.
By making them protected, Point3D can use x and y in the << operator.
This is exactly the scenario your class notes describe.
Rule: Use protected when you KNOW derived classes need direct access to the member.
SECTION 13 : EXAM QUICK REFERENCE
13.1 Instant Identification Rules

⚡ 3-Second Identification Rule


See class B : public A → INHERITANCE (is-a)
See A obj; inside class → COMPOSITION (has-a strong)
See A* obj; pointer → AGGREGATION (has-a weak)

Constructor output: Base first, Derived second


Destructor output: Derived first, Base last (LIFO)
See protected: → Accessible in class + derived only

13.2 Access Modifier Quick Table


Modifier Same Class Derived Class main() / Outside

public ✅ Yes ✅ Yes ✅ Yes

protected ✅ Yes ✅ Yes ❌ No

private ✅ Yes ❌ No ❌ No

13.3 Common Exam Errors


Mistake Correct Rule
Getting constructor order Base constructor ALWAYS runs first, then derived
wrong
Accessing private in derived Private is NEVER accessible in derived — use getter or protected
Protected member from Protected can NOT be called from main() via object
main()
Private constructor in base Causes compile error — derived cannot be instantiated
Parameterized base, no init Must pass base args via initializer list in derived constructor
list
Forgetting A::func() syntax Use scope resolution (::) to call overridden base functions
Static not inheritable Static IS accessible in derived class AND in main()

13.4 Master Summary Table


Topic Key Rule Code Signal Exam Tip

Inheritance is-a relationship class B : public A Access base via obj


directly

Constructor Order Base FIRST, Derived A() before B() FIFO construction
SECOND

Destructor Order Derived FIRST, Base ~B() before ~A() LIFO destruction
LAST

public members Accessible everywhere public: void f() obj.f() works in main()

protected members Class + Derived only protected: int x; NOT via obj in main()

private members Own class only private: int secret; Use getter to expose

Param init in child Use initializer list : Base(args) Order follows declaration

Static in derived Shared, accessible always static int count; Same value everywhere

Function override Derived replaces base Same name + params Use A::f() for base ver.

Scope resolution Call specific version obj.A::print() :: used for base call

Empty class size Minimum 1 byte sizeof(B) = 1 Compiler guarantee

These notes have been prepared with the assistance of AI; therefore, they may contain some errors.
You are kindly requested to report any inaccuracies you may find.
@ali_ibn_akhtar | Abu Bakar Ali | OOP C++ — Inheritance Notes

You might also like