0% found this document useful (0 votes)
21 views42 pages

Assignments For C++

The document contains a series of C++ programming assignments focusing on memory management, class design, operator overloading, and polymorphism. It includes tasks such as creating classes with constructors and destructors, implementing dynamic memory allocation, and using RTTI for type identification. Each assignment provides code examples and requirements for functionality, ensuring proper memory handling and object-oriented principles.

Uploaded by

patilniraj277
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)
21 views42 pages

Assignments For C++

The document contains a series of C++ programming assignments focusing on memory management, class design, operator overloading, and polymorphism. It includes tasks such as creating classes with constructors and destructors, implementing dynamic memory allocation, and using RTTI for type identification. Each assignment provides code examples and requirements for functionality, ensuring proper memory handling and object-oriented principles.

Uploaded by

patilniraj277
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
You are on page 1/ 42

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;
}

You might also like