PCC UNIT 3 NOTES+Question Bank
PCC UNIT 3 NOTES+Question Bank
Inheritance in C++
Base Class: The parent class that contains common attributes and methods for reuse. It can
have members with different access levels:
Derived Class: The child class that inherits properties from the base class. It can add new
attributes or override existing ones
Types of Inheritance
Single Inheritance: One derived class inherits from one base class
Hierarchical Inheritance: Multiple derived classes inherit from a single base class
Multilevel Inheritance: A chain of inheritance where one derived class becomes the base
class for another
Access specifiers (public, protected, private) determine how members of the base class can
be accessed by derived classes
Ambiguity arises when a derived class inherits from multiple base classes with methods or
attributes of the same name. This can be resolved using:
Scope Resolution Operator: Explicitly specify which base class's member to access
Method Overriding: The derived class's method can override the base class's method
Constructors initialize objects, while destructors release resources. The base class's
constructor is called before the derived class's constructor, and vice versa for destructors
Abstract Classes
An abstract class cannot be instantiated and contains at least one pure virtual function,
which must be implemented by derived classes
Friend Classes
A friend class can access the private and protected members of another class, establishing a
one-way relationship .
Nested Classes
A nested class is defined within another class and can encapsulate related functionality
Pointers in C++
A pointer stores the address of another variable. Pointers can be used for dynamic memory
management, allowing for efficient memory allocation and deallocation
using new and delete
Pointer to Objects
Pointers can also point to objects, allowing access to an object's members using the arrow
operator (->)
The this pointer refers to the current instance of a class, allowing access to its members
Arrays vs Pointers
Arrays are static and allocated at compile time, while pointers are dynamic and can be
allocated or freed at runtime
Base Class- The parent class (or superclass) that contains common attributes and methods to be
inherited.
Derived Class- The child class (or subclass) that inherits from the base class and can add or
override members.
Output:
This is the base class.
This is the derived class.
Single Inheritance: One derived class inherits from one base class.
Multiple Inheritance: One derived class inherits from multiple base classes.
Hierarchical Inheritance: Multiple derived classes inherit from a single base class.
Multilevel Inheritance: A derived class inherits from another derived class, forming a chain.
Single Inheritance is the simplest form where one class inherits from one base class.
Syntax:
class Base {
// base class members
};
class Derived : public Base {
// derived class members
};
Example:
#include <iostream>
using namespace std;
class Base {
public:
void show() {
cout << "Base class method." << endl;
}
};
class Derived : public Base {
public:
void display() {
cout << "Derived class method." << endl;
}
};
int main() {
Derived obj;
obj.show(); // Inherited from Base class
obj.display(); // Defined in Derived class
return 0;
}
Output:
Ambiguity occurs when a derived class inherits from multiple base classes that have members
(methods or variables) with the same name. The compiler cannot decide which base class
member to use, causing ambiguity.
If both base classes have a method with the same name, and the derived class calls that method
without specifying which base class it belongs to, the compiler throws an ambiguity error.
Example of Ambiguity
#include <iostream>
using namespace std;
class Base1 {
public:
void show() {
cout << "Base1 show()" << endl;
}
};
class Base2 {
public:
void show() {
cout << "Base2 show()" << endl;
}
};
class Derived : public Base1, public Base2 {
// Inherits show() from both Base1 and Base2
};
int main() {
Derived obj;
// obj.show(); // Ambiguous: compiler doesn't know which
show() to call
obj.Base1::show(); // Resolving ambiguity using scope
resolution
obj.Base2::show(); // Resolving ambiguity using scope
resolution
return 0;
}
Output:
Base1 show()
Base2 show()
Diamond Problem
Without virtual inheritance, D gets two copies of A's members (one via B and one via C),
causing ambiguity and inefficiency.
By declaring inheritance as virtual, C++ ensures only one shared copy of the base class A is
inherited by the final derived class D.
Syntax
Programming Example
#include <iostream>
using namespace std;
Output:
Summary
Virtual inheritance ensures only one instance of the base class is shared.
In inheritance, base class constructor is called first, then the derived class constructor.
Destructor
It cleans up resources.
In inheritance, derived class destructor is called first, then the base class destructor.
Object
Derived class destructor → Base class destructor
Destruction
Programming Example
#include <iostream>
using namespace std;
class Base {
public:
Base() {
cout << "Base class constructor called" << endl;
}
~Base() {
cout << "Base class destructor called" << endl;
}
};
Output:
Hybrid inheritance helps in building complex relationships between classes and improves code
reusability. It can sometimes lead to the diamond problem, which is solved using virtual
inheritance in C++.
Programming Example
#include <iostream>
using namespace std;
class A {
public:
void displayA() {
cout << "This is class A" << endl;
}
};
class B : public A {
public:
void displayB() {
cout << "This is class B" << endl;
}
};
class C : public A {
public:
void displayC() {
cout << "This is class C" << endl;
}
};
class D : public B, public C {
public:
void displayD() {
cout << "This is class D" << endl;
}
};
int main() {
D obj;
// obj.displayA(); // Ambiguity, must specify path
obj.B::displayA(); // Solves ambiguity
obj.displayB();
obj.displayC();
obj.displayD();
return 0;
}
Output
This is class A
This is class B
This is class C
This is class D
Declaration:
int *ptr; → declares a pointer to an integer.
Initialization:
ptr = &x; → assigns the address of variable x to pointer ptr.
Dereferencing:
*ptr gives the value stored at the memory address pointed by ptr.
Programming Example
#include <iostream>
using namespace std;
int main() {
int num = 10;
int *ptr; // Declaring pointer
ptr = # // Storing address of num in ptr
cout << "Value of num: " << num << endl;
cout << "Address of num: " << &num << endl;
cout << "Pointer ptr stores: " << ptr << endl;
cout << "Value at address ptr points to: " << *ptr << endl;
return 0;
}
Output:
Value of num: 10
Address of num: 0x61ff08 // (actual address may vary)
Pointer ptr stores: 0x61ff08 // (same as above)
Value at address ptr points to: 10
Uses of Pointers:
1) new Operator:
2) delete Operator:
Example
#include <iostream>
using namespace std;
int main() {
int *ptr;
// Allocating memory
ptr = new int;
*ptr = 25;
cout << "Value: " << *ptr << endl;
// Deallocating memory
delete ptr;
return 0;
}
Output:
Value: 25
It points to the current object (the object that invoked the member function).
Useful when local variables have the same name as data members.
Key Points:
Example
#include <iostream>
using namespace std;
class Student {
private:
int id;
public:
void setId(int id) {
this->id = id; // Using 'this' to distinguish between
member and parameter
}
void display() {
cout << "Student ID: " << this->id << endl;
}
};
int main() {
Student s1;
s1.setId(101);
s1.display();
return 0;
}
Output
Student ID: 101
Output
Output
Output