Assignments for C++ preparation
1) I) allocate memory for 1 int and store 420 value inside. now release it.
Answer –
#include <iostream>
using namespace std;
int main() {
int* ptr = new int;
*ptr = 420;
cout << "Value: " << *ptr << endl;
delete ptr;
return 0;
}
II) allocate memory for 10 characters on heap store 10 characters ,display them and release that
memory.
Answer-
#include <iostream>
using namespace std;
int main() {
// Allocate memory for 10 characters
char* ch = new char[10];
// Store 10 characters (A to J)
for (int i = 0; i < 10; i++) {
ch[i] = 'A' + i;
}
// Display the characters
cout << "Characters: ";
for (int i = 0; i < 10; i++) {
cout << ch[i] << " ";
}
cout << endl;
// Free the memory
delete[] ch;
return 0;
}
2) define a class to meet following requirements
First f1("hello","welcome"); f1.disp
First f2=f1; f2.disp
First f3;
f3=f1 f3.disp
make sure neither memory leak nor dangling pointer arises in the code
Answer-
#include <iostream>
#include <string> // use string instead of char*
using namespace std;
class First {
string str1;
string str2;
public:
// Default constructor
First() : str1(""), str2("") {}
// Parameterized constructor
First(const string& s1, const string& s2) : str1(s1), str2(s2) {}
// Display function
void disp() const {
cout << "str1: " << str1 << ", str2: " << str2 << endl;
}
};
int main() {
First f1("hello", "welcome");
f1.disp();
First f2 = f1; // copy constructor (automatically handled)
f2.disp();
First f3; // default constructor
f3 = f1; // assignment operator (automatically handled)
f3.disp();
return 0;
}
3) define a class “Voter”,its members should be int id, char *name, char *address.
Define input() , show() methods , Accept from user , how many voters he has .
[DMA], Depending upon that , allocate the memory,invoke input() and get the data from user.
Now invoke show method for all the objects created. make sure neither memory leak nor dangling
pointer arises in the code
Answer –
#include <iostream>
#include <cstring>
using namespace std;
class Voter {
int id;
char* name;
char* address;
public:
// Default constructor with initialization
Voter() {
id = 0;
name = new char[1];
name[0] = '\0';
address = new char[1];
address[0] = '\0';
}
// Destructor
~Voter() {
delete[] name;
delete[] address;
}
// Input method using strcpy_s
void input() {
char temp[100];
cout << "Enter ID: ";
cin >> id;
cin.ignore(); // remove leftover newline
cout << "Enter Name: ";
cin.getline(temp, 100);
delete[] name;
name = new char[strlen(temp) + 1];
strcpy_s(name, strlen(temp) + 1, temp); // safer strcpy
cout << "Enter Address: ";
cin.getline(temp, 100);
delete[] address;
address = new char[strlen(temp) + 1];
strcpy_s(address, strlen(temp) + 1, temp); // safer strcpy
}
// Show method
void show() const {
cout << "ID: " << id << ", Name: " << name << ", Address: " << address << endl;
}
};
int main() {
int n;
cout << "How many voters? ";
cin >> n;
Voter* voters = new Voter[n];
for (int i = 0; i < n; i++) {
cout << "\nEnter details for Voter " << i + 1 << ":\n";
voters[i].input();
}
cout << "\n--- Voter Details ---\n";
for (int i = 0; i < n; i++) {
voters[i].show();
}
delete[] voters;
return 0;
}
4) Sample s1(10)
s1-300
s1=600
int data=s1
s1+s2
++s1
s1++
s1+=20
100+s1
cin>>s1
cout<<s1
Answer –
#include <iostream>
using namespace std;
class Sample {
int value;
public:
// Constructor
Sample(int v = 0) : value(v) {}
// Operator overloading
Sample operator-(int x) const {
return Sample(value - x);
}
Sample& operator=(int x) {
value = x;
return *this;
}
operator int() const { // Type conversion to int
return value;
}
Sample operator+(const Sample& other) const {
return Sample(value + other.value);
}
Sample& operator++() { // Pre-increment
++value;
return *this;
}
Sample operator++(int) { // Post-increment
Sample temp = *this;
value++;
return temp;
}
Sample& operator+=(int x) {
value += x;
return *this;
}
// Friend functions for input/output and int + Sample
friend Sample operator+(int x, const Sample& s);
friend ostream& operator<<(ostream& out, const Sample& s);
friend istream& operator>>(istream& in, Sample& s);
};
// int + Sample
Sample operator+(int x, const Sample& s) {
return Sample(x + s.value);
}
// Output
ostream& operator<<(ostream& out, const Sample& s) {
out << s.value;
return out;
}
// Input
istream& operator>>(istream& in, Sample& s) {
in >> s.value;
return in;
}
int main() {
Sample s1(10), s2(5), s3;
s1 = 600; // assignment
cout << "s1 = " << s1 << endl;
s1 = s1 - 300; // subtraction
cout << "s1 - 300 = " << s1 << endl;
int data = s1; // type conversion
cout << "data = " << data << endl;
s3 = s1 + s2; // addition
cout << "s1 + s2 = " << s3 << endl;
++s1; // pre-increment
cout << "++s1 = " << s1 << endl;
s1++; // post-increment
cout << "s1++ = " << s1 << endl;
s1 += 20; // operator +=
cout << "s1 += 20 = " << s1 << endl;
s3 = 100 + s1; // int + Sample
cout << "100 + s1 = " << s3 << endl;
cout << "Enter value for s1: ";
cin >> s1; // input
cout << "You entered: " << s1 << endl; // output
return 0;
}
5) RTTI virtual or pure virtual function collect child class addresses in parent pointer, child class
object in parent reference, array of parent pointers storing addresses of child classes dynamic_cast
Answer –
#include <iostream>
#include <typeinfo>
using namespace std;
class Base {
public:
virtual void show() { cout << "Base show()\n"; }
virtual ~Base() {}
};
class Derived : public Base {
public:
void show() override { cout << "Derived show()\n"; }
void derivedOnly() { cout << "Derived-only method\n"; }
};
int main() {
// 1. Parent pointer to child object
Base* ptr = new Derived();
ptr->show();
// 2. Parent reference to child object
Derived d;
Base& ref = d;
ref.show();
// 3. Array of parent pointers to child objects
Base* arr[2];
arr[0] = new Derived();
arr[1] = new Derived();
for (int i = 0; i < 2; i++)
arr[i]->show();
// 4. RTTI - typeid
cout << "Type of ptr: " << typeid(*ptr).name() << endl;
// 5. dynamic_cast
Derived* down = dynamic_cast<Derived*>(ptr);
if (down) {
cout << "Downcast successful\n";
down->derivedOnly();
}
else {
cout << "Downcast failed\n";
}
// Clean up
delete ptr;
delete arr[0];
delete arr[1];
return 0;
}
6)
class B
int y;
void disp2() { how will you access "x" here? }
class A
int x;
void disp1(){}
do not change the order of above classes
Answer-
#include <iostream>
using namespace std;
class A; // forward declaration
class B {
int y;
public:
void disp2(A* a); // declare function that accepts A*
};
class A {
int x;
public:
A(int a) { x = a; }
friend class B; // allow B to access private members
void disp1() { cout << "x = " << x << endl; }
};
void B::disp2(A* a) {
cout << "Accessing A's x from B: " << a->x << endl;
}
int main() {
A a1(100);
B b1;
b1.disp2(&a1);
return 0;
}
7) Given
class A
private:
int* ptr; // allocate memory inside heap
int len;
void disp(){ // incomplete }
};
while creating object of above class pass int array and its length
make sure when you call disp , it should display the whole array which was passed while creating
array
also make sure you can perform following operations on the objects of class A
cout<<ref1[1]; // ref1 is assumed to be the object of A
ref1[0]=1000;
Answer-
#include <iostream>
using namespace std;
class A {
private:
int* ptr; // dynamic array
int len;
public:
// Constructor: takes an array and its length
A(int arr[], int l) {
len = l;
ptr = new int[len];
for (int i = 0; i < len; i++) {
ptr[i] = arr[i];
}
}
// Destructor to free memory
~A() {
delete[] ptr;
}
// Display function
void disp() {
for (int i = 0; i < len; i++) {
cout << ptr[i] << " ";
}
cout << endl;
}
// Overload [] for non-const access (e.g., ref1[0] = 1000)
int& operator[](int index) {
if (index >= 0 && index < len)
return ptr[index];
throw out_of_range("Index out of bounds");
}
// Optional: Overload [] for const access
int operator[](int index) const {
if (index >= 0 && index < len)
return ptr[index];
throw out_of_range("Index out of bounds");
}
};
int main() {
int arr[] = { 10, 20, 30, 40, 50 };
A ref1(arr, 5);
cout << "Original array: ";
ref1.disp();
cout << "Access ref1[1]: " << ref1[1] << endl;
ref1[0] = 1000;
cout << "After changing ref1[0] to 1000: ";
ref1.disp();
return 0;
}
Day 7 Assignment : C++
1)Create a base class Weapon. Define virtual
function “void attack()” in it.
Define following sub classes for this class.
A) Gun b) Sword c) Rifle
“Rifle” class will have one more function “Chambering
()”. create an array of pointer to Weapon
having 3 elements.
In this array , store the instances of child classes.
Traverse the array , find out where exactly “Rifle” is
stored using RTTI (dynamic_cast) , and invoke
“Chambering ()” function along with “attack()”
function.
/*
1) Create a base class Weapon. Define virtual function “void attack()” in it.
Define following sub classes for this class. A) Gun b)
Sword c) Rifle
“Rifle” class will have one more function “Chambering ()”. create an array of pointer
to Weapon having 3 elements.
In this array , store the instances of child classes.
Traverse the array , find out where exactly “Rifle” is stored using RTTI (dynamic_cast) , and
invoke “Chambering ()” function along with “attack()” function.
*/
#include<iostream>
using namespace std;
// heirarchical inheritance
class Weapon // parent
public:
virtual void attack() // virtual method i.e. late binding (content checked)(so all child
methods will be virtual automatically )
cout << "Attacking ..." << endl;
};
class Gun :public Weapon // child 1
public:
void attack() override // override keyword is used i.e. if you define method with
different arguments , you will get error
cout << "Attacking using Gun " << endl;
};
class Sword : public Weapon // child 2
public:
void attack() override // override keyword is used i.e. if you define method with
different arguments , you will get error
cout << "Attacking using Sword" << endl;
}
};
class Rifle :public Weapon // child 3
public:
void attack() override // override keyword is used i.e. if you define method with
different arguments , you will get error
cout << "Attacking using Rifle" << endl;
void Chambering() // extra method
cout << "Inside Chamberring method" << endl;
};
int main()
Weapon* arr[3]; // array of pointer to Weapon having 3 elements.
// storing instance of childs in array
arr[0] = new Gun; // child 1
arr[1] = new Sword; // child 2
arr[2] = new Rifle; // child 3
for (int i = 0; i < 3; i++) // traversing the array
arr[i]->attack();
//find out where exactly “Rifle” is stored using RTTI(dynamic_cast)
Rifle *d = dynamic_cast<Rifle*>(arr[i]);
if(d) // in 'd' address is stored of Rifle (if condition satisfies )
// invoke “Chambering()” function along with “attack()” function.
d->Chambering();
}
return 0;
o/p,
2)Create a base class Animal. Declare pure virtual
function “void makeSound()” in it.
Define following sub classes for this class.
A) Dog b) Cat c) Tiger
“Tiger” class will have one more function
“hunting()”. create a global
function “void perform() which accepts pointer of
type Animal so that it can invoke “makeSound()”
function polymorphically. Inside this function find
out where exactly where “Tiger” is stored using RTTI
(dynamic_cast) , and invoke “hunting()” function
along with “makeSound()” function.
/*
2) Create a base class Animal. Declare pure virtual function “void makeSound()” in it.
Define following sub classes for this class.
A) Dog b) Cat c) Tiger
“Tiger” class will have one more function “hunting()”.
create a global function “void perform() which accepts pointer of type Animal so that it can
invoke “makeSound()” function polymorphically.
Inside this function find out where exactly where “Tiger” is stored using RTTI (dynamic_cast) ,
and invoke “hunting()” function along with “makeSound()” function.
*/
#include<iostream>
using namespace std;
class Animal // base class Animal
public:
// to call functions polymorphically will use virtual function
virtual void makesound() = 0; // pure virtual function “void makeSound()” //
overidden method
};
class Dog :public Animal
void makesound() override // Overiding method
cout << "Dog Barks" << endl;
};
class Cat :public Animal
void makesound() override // Overiding method
{
cout << "Cat meows " << endl;
};
class Tiger : public Animal
public:
void makesound() override // Overiding method
cout << "TIger roars" << endl;
void hunting() // extra method
cout << "Tiger is Hunting " << endl;
};
// global function “void perform() which accepts pointer of type Animal so that it can invoke
“makeSound()” function polymorphically
void perform(Animal *ptr) // accepts pointer
// find out where exactly where “Tiger” is stored using RTTI (dynamic_cast)
Tiger *T=dynamic_cast<Tiger*>(ptr);
if (T) // if condition satisfy , Tiger address will go under 'T'
// invoke “hunting()” function along with “makeSound()” function.
T->hunting();
ptr->makesound(); // calling function polymorphically
int main()
Tiger obj1; // child 1 object
Cat obj2; // child 2 object
Dog obj3; // child 3 object
perform(&obj1); // passing address of child 1
perform(&obj2); // passing address of child 2
perform(&obj3); // passing address of child 3
return 0;
o/p,
3)Create a base class Cricket. Define virtual function
“void play()” in it.
Define following sub classes for this class.
A) FiftyOver b) Test c) TwentyOver
“Test” class will have one more function
“daywise_summary()”.
create a global function “void doit() which
accepts reference of type Cricket so that it can
invoke “play()” function polymorphically. Inside
this function find out where exactly where “Test”
is stored using RTTI (dynamic_cast) , and invoke
“daywise_summary()” function along with “play()”
function. [ handle bad_cast exception ]
/*
3) Create a base class Cricket. Define virtual function “void play()” in it.
Define following sub classes for this class.
A) FiftyOver b) Test c) TwentyOver
“Test” class will have one more function “daywise_summary()”.
create a global function “void doit() which accepts reference of type Cricket so that it can
invoke “play()” function polymorphically.
Inside this function find out where exactly where “Test” is stored using RTTI (dynamic_cast) ,
and invoke “daywise_summary()” function along with “play()” function. [ handle bad_cast
exception ]
*/
#include<iostream>
using namespace std;
class Cricket // base class Cricket
public:
virtual void play() //virtual function “void play()”
cout << "PLay Cricket " << endl;
}
};
class FiftyOver :public Cricket
void play() override
cout << "Match will be having Fifty over" << endl;
};
class Test :public Cricket
public:
void play() override
cout << "Test cricket Match" << endl;
// “Test” class will have one more function “daywise_summary()”.
void daywise_summary()
cout << "This is daywise summary of Test Match" << endl;
};
class TwentyOver :public Cricket
virtual void play() override
cout << "It will be a Twenty over Cricket match " << endl;
};
// global function “void doit() which accepts reference of type Cricket so that it can invoke
“play()” function polymorphically
void doit(Cricket &ref) // Accepts References of objects
ref.play(); // will use dot to access
// find out where exactly where “Test” is stored using RTTI (dynamic_cast)
// invoke “daywise_summary()” function along with “play()” function. [ handle
bad_cast exception ]
try // handled exception
Test T = dynamic_cast<Test&>(ref);
T.daywise_summary();
catch (bad_cast& r) // its like "class cast exception " in java .
cout << "in catch block " << r.what() << endl; // what is a
function
int main()
// objects created
FiftyOver obj1;
TwentyOver obj2;
Test obj3;
// objects passed to a function
doit(obj1);
doit(obj2);
doit(obj3);
return 0;
o/p,
4)Create a base class Cricket. Declare pure virtual
function “void play()” in it.
Define following sub classes for this class.
A) FiftyOver b) Test c) TwentyOver
“Test” class will have one more function
“daywise_summary()”.
Create an array of pointer
to “Cricket” class having 3 elements. Store child class
objects into this array.
Now using using RTTI , find out where is “Test”,
and call “daywise_summary()” along with “play()”
function.
/*
4) Create a base class Cricket. Declare pure virtual function “void play()” in it.
Define following sub classes for this class.
A) FiftyOver b) Test c) TwentyOver
“Test” class will have one more function “daywise_summary()”.
Create an array of pointer to “Cricket” class having 3 elements. Store child class objects into
this array.
Now using using RTTI , find out where is “Test”, and call “daywise_summary()” along with
“play()” function.
*/
#include<iostream>
using namespace std;
class Cricket // base class
public:
virtual void play() = 0; // pure virtual function (overridden method)
};
class FiftyOver :public Cricket // child 1
void play() override // overriding method
cout << "playing fifty over match " << endl;
};
class Test :public Cricket // child 2
public:
void play() override // overriding method
cout << "playing Test match " << endl;
}
void daywise_summary() // extra method
cout << "This is day wise summary of test match " << endl;
};
class TwentyOver : public Cricket // child 3
void play() override // overiding method
cout << "playing twenty over match " << endl;
};
int main()
// Create an array of pointer to “Cricket” class having 3 elements
Cricket* arr[3];
// Store child class objects into this array
Test obj1;
FiftyOver obj2;
TwentyOver obj3;
arr[0] = &obj1;
arr[1] = &obj2;
arr[2] = &obj3;
// Now using using RTTI, find out where is “Test”, and call “daywise_summary()” along
with “play()” function.
for (int i = 0; i < 3; i++)
arr[i]->play();
Test* ptr = dynamic_cast<Test*>(arr[i]);
if (ptr)
{
ptr->daywise_summary();
return 0;
o/p,
5) Create a base class “StorageDevice”.Define
virtual function “void store()” in it.
Define
following sub classes for this class.
A) HardDisk b) CD c)
PenDrive.
define “store()” in these classes.
now write a global function "perform()" which will
accept "StorageDevice class reference" as an
argument. In this function using RTTI invoke
"store()" method of only “PenDrive”. [ handle
bad_cast exception ]
From main function try to call “perform()” function
by passing various child classes.
/*
5) Create a base class “StorageDevice”.Define virtual function
“void store()” in it.
Define following sub classes for this class.
A) HardDisk b) CD c) PenDrive.
define “store()” in these classes.
now write a global function "perform()" which will accept "StorageDevice class reference" as
an argument.
In this function using RTTI invoke "store()" method of only “PenDrive”. [ handle bad_cast
exception ]
From main function try to call “perform()” function by passing various child classes.
*/
#include<iostream>
using namespace std;
// base class “StorageDevice”
class StorageDevice
{
public:
virtual void store()
cout << "stored in Storage Device " << endl;
};
// sub classes for this class.
// A) HardDisk b) CD c) PenDrive.
// define “store()” in these classes.
class HardDisk :public StorageDevice
public:
void store() override
cout << "stored in Harddisk" << endl;
};
class CD : public StorageDevice
public:
void store() override
cout << "stored in CD" << endl;
};
class Pendrive : public StorageDevice
public:
void store() override
cout << "stored in Pendrive" << endl;
};
// global function "perform()" which will accept "StorageDevice class reference" as an
argument.
void perform(StorageDevice &ref) // accept reference
//using RTTI invoke "store()" method of only “PenDrive”.[handle bad_cast exception]
try
Pendrive &p = dynamic_cast<Pendrive&>(ref);
cout << "Detected Pendrive: " << endl;;
p.store();
catch (bad_cast &e)
cout << "Not a Pendrive object: " << e.what() << endl;
int main()
Pendrive p;
CD c;
HardDisk h;
// passing objects
perform(p); // this will work
perform(c); // here will get exeption
perform(h); // here will get exception
return 0;
o/p,
6) Create a base class “Subject”.Declare pure
virtual function “void maxmarks()” in it. Define
following sub classes for this class. A) Maths b)
History c) English. Define “maxmarks” in these
classes. In main function, create array of pointer
to Subject, which will contain objects of these
three sub classes. Using RTTI, find out where is
“History” and call its maxmarks() method.
-
/*
6) Create a base class “Subject”.
Declare pure virtual function “void maxmarks()” in it.
Define following sub classes for this class.
A) Maths b) History c) English.
Define “maxmarks” in these classes.
In main function, create array of pointer to Subject, which will contain objects of these three
sub classes.
Using RTTI, find out where is “History” and call its maxmarks() method.
*/
#include<iostream>
using namespace std;
// Create a base class “Subject”.
class Subject
public:
// Declare pure virtual function “void maxmarks()” in it.
virtual void maxmarks() = 0;
};
// Define following sub classes for this class.
// A) Maths b) History c) English.
// Define “maxmarks” in these classes.
class Maths :public Subject
public:
void maxmarks() override
cout << "Maximum marks in Subject Maths" << endl;
};
class History : public Subject
public:
void maxmarks() override
cout << "Maximum marks in Subject History" << endl;
};
class English : public Subject
public:
void maxmarks() override
{
cout << "Maximum marks in Subject English" << endl;
};
//,
//
int main()
// In main function, create array of pointer to Subject
Subject* arr[3];
// which will contain objects of these three sub classes.
English E;
History H;
Maths M;
arr[0] = &E;
arr[1] = &H;
arr[2] = &M;
// Using RTTI, find out where is “History” and call its maxmarks() method.
for (int i = 0; i < 3; i++)
History* H = dynamic_cast<History*>(arr[i]);
if (H)
H->maxmarks();
}
}
return 0;
o/p,
OOPS
heap and stack based object
constructors
default,parameterized
copy constructor
destructor - calling explicitly in case of heap based object
array of object
DMA - array of object
use of "delete" in case of DMA
answer-
// Only if using Visual Studio; optional
#include <iostream>
#include <cstring>
using namespace std;
class Student {
private:
char* name;
int age;
public:
// Default Constructor
Student() {
name = new char[1];
name[0] = '\0';
age = 0;
cout << "Default Constructor Called\n";
}
// Parameterized Constructor
Student(const char* n, int a) {
name = new char[strlen(n) + 1];
strcpy_s(name, strlen(n) + 1, n); // Safe version of strcpy
age = a;
cout << "Parameterized Constructor Called\n";
}
// Copy Constructor (deep copy)
Student(const Student& other) {
name = new char[strlen(other.name) + 1];
strcpy_s(name, strlen(other.name) + 1, other.name);
age = other.age;
cout << "Copy Constructor Called\n";
}
// Destructor
~Student() {
cout << "Destructor Called for: " << name << endl;
delete[] name;
}
void show() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
cout << "Stack Object:\n";
Student s1("Alice", 21); // stack object
s1.show();
cout << "\nHeap Object:\n";
Student* s2 = new Student("Bob", 25); // heap object
s2->show();
delete s2; // explicit destructor call
cout << "\nArray of Stack Objects:\n";
Student arr[2] = { Student("Charlie", 18), Student("Diana", 20) };
for (int i = 0; i < 2; i++) {
arr[i].show();
}
cout << "\nDMA - Array of Heap Objects:\n";
Student* dynArr = new Student[2]; // calls default constructor twice
dynArr[0] = Student("Eve", 22); // assignment (uses default operator=)
dynArr[1] = Student("Frank", 23);
for (int i = 0; i < 2; i++) {
dynArr[i].show();
}
delete[] dynArr; // release array of heap objects
return 0;
}
Friend function
forward declaration
syntax for defining member function outside the class.
Answer-
#include <iostream>
using namespace std;
// Forward declaration of class B
class B;
class A {
private:
int a;
public:
A(int val) { a = val; }
// Friend function declaration
friend void showSum(A, B);
};
// Class B defined after forward declaration
class B {
private:
int b;
public:
B(int val) { b = val; }
// Friend function declaration
friend void showSum(A, B);
};
// Friend function defined outside class
void showSum(A objA, B objB) {
cout << "Sum = " << (objA.a + objB.b) << endl;
}
int main() {
A obj1(10);
B obj2(20);
showSum(obj1, obj2); // Accesses private data from both classes
return 0;
}
Operator Overloading
assignment
pre-post increment/decrement
all arithmetic operators
> , <, ==
compound assignment
primitive on the left side during operator overloading
need of friend function inside operator overloading
insertion operator overloading
answer-
#include <iostream>
using namespace std;
class Sample {
int value;
public:
// Constructors
Sample() : value(0) {}
Sample(int v) : value(v) {}
// Display
void show() const { cout << "Value: " << value << endl; }
// Assignment operator
Sample& operator=(const Sample& other) {
value = other.value;
return *this;
}
// Pre-increment (++obj)
Sample& operator++() {
++value;
return *this;
}
// Post-increment (obj++)
Sample operator++(int) {
Sample temp = *this;
value++;
return temp;
}
// Pre-decrement (--obj)
Sample& operator--() {
--value;
return *this;
}
// Post-decrement (obj--)
Sample operator--(int) {
Sample temp = *this;
value--;
return temp;
}
// Arithmetic operators
Sample operator+(const Sample& s) const {
return Sample(value + s.value);
}
Sample operator-(const Sample& s) const {
return Sample(value - s.value);
}
Sample operator*(const Sample& s) const {
return Sample(value * s.value);
}
Sample operator/(const Sample& s) const {
return Sample(value / s.value);
}
// Comparison operators
bool operator>(const Sample& s) const { return value > s.value; }
bool operator<(const Sample& s) const { return value < s.value; }
bool operator==(const Sample& s) const { return value == s.value; }
// Compound assignment (+=)
Sample& operator+=(int num) {
value += num;
return *this;
}
// Insertion operator (cout << obj)
friend ostream& operator<<(ostream& out, const Sample& s);
// Friend function to allow primitive on left (e.g., 100 + obj)
friend Sample operator+(int num, const Sample& s);
};
// Insertion operator
ostream& operator<<(ostream& out, const Sample& s) {
out << s.value;
return out;
}
// Primitive on left
Sample operator+(int num, const Sample& s) {
return Sample(num + s.value);
}
int main() {
Sample s1(10), s2(20), s3;
cout << "Assignment:\n";
s3 = s1;
cout << "s3 = " << s3 << "\n";
cout << "\nPre/Post Increment & Decrement:\n";
++s1;
cout << "++s1 = " << s1 << "\n";
s1++;
cout << "s1++ = " << s1 << "\n";
--s1;
cout << "--s1 = " << s1 << "\n";
s1--;
cout << "s1-- = " << s1 << "\n";
cout << "\nArithmetic (+, -, *, /):\n";
cout << "s1 + s2 = " << (s1 + s2) << "\n";
cout << "s2 - s1 = " << (s2 - s1) << "\n";
cout << "s1 * s2 = " << (s1 * s2) << "\n";
cout << "s2 / s1 = " << (s2 / s1) << "\n";
cout << "\nComparison:\n";
cout << (s1 > s2 ? "s1 > s2\n" : "s1 <= s2\n");
cout << (s1 < s2 ? "s1 < s2\n" : "s1 >= s2\n");
cout << (s1 == s2 ? "s1 == s2\n" : "s1 != s2\n");
cout << "\nCompound Assignment:\n";
s1 += 5;
cout << "s1 += 5: " << s1 << "\n";
cout << "\nPrimitive on Left:\n";
Sample s4 = 100 + s1; // friend operator+
cout << "100 + s1 = " << s4 << "\n";
cout << "\nInsertion Operator:\n";
cout << "s1 = " << s1 << "\n";
return 0;
}
conversion
primitive to user defined
user defined to primitive
answer-
#include <iostream>
using namespace std;
class Distance {
int meter;
public:
// Default constructor
Distance() : meter(0) {}
// Parameterized constructor — primitive to user-defined
Distance(int m) {
meter = m;
cout << "Primitive to User-defined Conversion Called\n";
}
// Member function — user-defined to primitive
operator int() {
cout << "User-defined to Primitive Conversion Called\n";
return meter;
}
void display() {
cout << "Distance = " << meter << " meters\n";
}
};
int main() {
// Primitive to user-defined
int x = 50;
Distance d1; // Default object
d1 = x; // Implicit call to constructor
d1.display();
// User-defined to primitive
int y;
y = d1; // Implicit call to operator int()
cout << "Converted int value = " << y << endl;
return 0;
}
virtual functions, pure virtual function , abstract class
answer-
#include <iostream>
using namespace std;
// Abstract class: contains pure virtual function
class Animal {
public:
// Virtual function (can be overridden)
virtual void speak() {
cout << "Animal speaks\n";
}
// Pure virtual function
virtual void sound() = 0; // = 0 means pure virtual
virtual ~Animal() {
cout << "Animal destroyed\n";
}
};
// Derived class 1
class Dog : public Animal {
public:
void speak() override {
cout << "Dog says: Woof!\n";
}
void sound() override {
cout << "Dog makes barking sound\n";
}
~Dog() {
cout << "Dog destroyed\n";
}
};
// Derived class 2
class Cat : public Animal {
public:
void speak() override {
cout << "Cat says: Meow!\n";
}
void sound() override {
cout << "Cat makes meowing sound\n";
}
~Cat() {
cout << "Cat destroyed\n";
}
};
int main() {
Animal* a1 = new Dog(); // Base class pointer → Dog object
Animal* a2 = new Cat(); // Base class pointer → Cat object
a1->speak(); // Dog's speak
a1->sound(); // Dog's sound
a2->speak(); // Cat's speak
a2->sound(); // Cat's sound
delete a1;
delete a2;
return 0;
}
upcasting with pointer and reference
answer-
#include <iostream>
using namespace std;
class Base {
public:
virtual void show() {
cout << "Base class show()" << endl;
}
virtual ~Base() {}
};
class Derived : public Base {
public:
void show() override {
cout << "Derived class show()" << endl;
}
};
int main() {
Derived d;
// Upcasting with pointer (Derived* → Base*)
Base* basePtr = &d; // Automatically allowed
basePtr->show(); // Calls Derived's show() due to virtual function
// Upcasting with reference (Derived& → Base&)
Base& baseRef = d; // Automatically allowed
baseRef.show(); // Calls Derived's show()
return 0;
}
parent class array stores child class objects
answer-
Example with virtual function:
#include <iostream>
using namespace std;
class Parent {
public:
virtual void speak() {
cout << "Parent speaking" << endl;
}
virtual ~Parent() {}
};
class Child1 : public Parent {
public:
void speak() override {
cout << "Child1 speaking" << endl;
}
};
class Child2 : public Parent {
public:
void speak() override {
cout << "Child2 speaking" << endl;
}
};
int main() {
// Array of Parent class pointers
Parent* arr[3];
// Store addresses of child objects in parent pointers
arr[0] = new Parent();
arr[1] = new Child1();
arr[2] = new Child2();
// Polymorphic calls
for (int i = 0; i < 3; i++) {
arr[i]->speak();
}
// Cleanup to avoid memory leaks
for (int i = 0; i < 3; i++) {
delete arr[i];
}
return 0;
}
function to accept parent class pointer and polymorphically invokes virtual or pure virtual function/s.
#include <iostream>
using namespace std;
class Parent {
public:
virtual void show() {
cout << "Parent show()" << endl;
}
virtual ~Parent() {}
};
class Child : public Parent {
public:
void show() override {
cout << "Child show()" << endl;
}
};
// Function accepts Parent pointer and calls virtual function
void display(Parent* p) {
p->show(); // polymorphic call: calls Child::show if p points to Child
}
int main() {
Parent p;
Child c;
display(&p); // Output: Parent show()
display(&c); // Output: Child show()
return 0;
}
Example with pure virtual function (Abstract class):
#include <iostream>
using namespace std;
class Parent {
public:
virtual void show() = 0; // pure virtual function = abstract class
virtual ~Parent() {}
};
class Child : public Parent {
public:
void show() override {
cout << "Child show()" << endl;
}
};
void display(Parent* p) {
p->show(); // polymorphic call
}
int main() {
// Parent p; // Error: cannot create object of abstract class
Child c;
display(&c); // Output: Child show()
return 0;
}
function to accept parent class reference and polymorphically invokes virtual or pure virtual
function/s.
answer-
Example with virtual function:
#include <iostream>
using namespace std;
class Parent {
public:
virtual void show() {
cout << "Parent show()" << endl;
}
virtual ~Parent() {}
};
class Child : public Parent {
public:
void show() override {
cout << "Child show()" << endl;
}
};
// Function accepts Parent reference and calls virtual function
void display(Parent& p) {
p.show(); // polymorphic call: calls Child::show if p is Child
}
int main() {
Parent p;
Child c;
display(p); // Output: Parent show()
display(c); // Output: Child show()
return 0;
}
Example with pure virtual function (Abstract class):
#include <iostream>
using namespace std;
class Parent {
public:
virtual void show() = 0; // pure virtual function
virtual ~Parent() {}
};
class Child : public Parent {
public:
void show() override {
cout << "Child show()" << endl;
}
};
void display(Parent& p) {
p.show(); // polymorphic call
}
int main() {
// Parent p; // Error: cannot instantiate abstract class
Child c;
display(c); // Output: Child show()
return 0;
}
downcasting (dynamic_cast) using pointer and reference.
bad_cast exception handling while using reference with dynamic_cast.
#include <iostream>
#include <typeinfo> // for std::bad_cast
using namespace std;
class Base {
public:
virtual void show() { cout << "Base class\n"; }
virtual ~Base() {}
};
class Derived : public Base {
public:
void show() override { cout << "Derived class\n"; }
void onlyInDerived() { cout << "Derived specific function\n"; }
};
void downcastWithPointer(Base* basePtr) {
Derived* dPtr = dynamic_cast<Derived*>(basePtr);
if (dPtr != nullptr) {
cout << "Downcast successful (pointer)\n";
dPtr->onlyInDerived();
}
else {
cout << "Downcast failed (pointer)\n";
}
}
void downcastWithReference(Base& baseRef) {
try {
Derived& dRef = dynamic_cast<Derived&>(baseRef);
cout << "Downcast successful (reference)\n";
dRef.onlyInDerived();
}
catch (bad_cast& e) {
cout << "Downcast failed (reference): " << e.what() << endl;
}
}
int main() {
Base b;
Derived d;
Base* basePtr1 = &b;
Base* basePtr2 = &d;
cout << "Using pointer:\n";
downcastWithPointer(basePtr1); // Should fail
downcastWithPointer(basePtr2); // Should succeed
cout << "\nUsing reference:\n";
downcastWithReference(b); // Should fail and catch exception
downcastWithReference(d); // Should succeed
return 0;
}
Imp note:
if the question contains a message:
program should not give any dangling pointer and memory leak problem, then you must
define copy constructor to perform deep copy
and
define destructor to release the heap based memory using "delete"
#include <iostream>
#include <cstring> // for strcpy_s
using namespace std;
class MyString {
char* str;
public:
MyString(const char* s = "") {
str = new char[strlen(s) + 1];
// Use strcpy_s(destination, size, source)
strcpy_s(str, strlen(s) + 1, s);
}
MyString(const MyString& other) {
str = new char[strlen(other.str) + 1];
strcpy_s(str, strlen(other.str) + 1, other.str);
cout << "Copy constructor called\n";
}
~MyString() {
delete[] str;
cout << "Destructor called\n";
}
void show() const {
cout << str << endl;
}
};
int main() {
MyString s1("Hello");
MyString s2 = s1;
s1.show();
s2.show();
return 0;
}