Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
2 views

answer cae2 oop

The document is a question bank for the Object Oriented Programming subject at G H Raisoni College of Engineering and Management, detailing various topics such as inheritance types, access specifiers, multiple inheritance, and hybrid inheritance. It includes example C++ programs demonstrating concepts like multilevel inheritance and multiple inheritance for employee information. Additionally, it covers constructors and destructors in derived classes, emphasizing their call order during object creation and destruction.

Uploaded by

panjabiji999
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

answer cae2 oop

The document is a question bank for the Object Oriented Programming subject at G H Raisoni College of Engineering and Management, detailing various topics such as inheritance types, access specifiers, multiple inheritance, and hybrid inheritance. It includes example C++ programs demonstrating concepts like multilevel inheritance and multiple inheritance for employee information. Additionally, it covers constructors and destructors in derived classes, emphasizing their call order during object creation and destruction.

Uploaded by

panjabiji999
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 54

G H Raisoni College of Engineering and Management, Pune

Department of Information Technology


Subject wise Common Question Bank (QB) for All Divisions

Class: SY A, B, C

Subject Name/Code: OBJECT ORIENTED PROGRAMMING

Subject Teacher Name(s): 1.Ms. Samrudhi Bhadane

2. Ms. Savita Mane

Note: Only 60% Questions can be asked from this QB in CAE. Rest of 40% questions will be from out
of this QB related to syllabus

Unit-III

Q. No. Question Statement

1. What is Inheritance? List the different types of Inheritance.

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a


class to inherit properties and behaviors (methods and attributes) from another class. This
helps in code reusability and the creation of hierarchical relationships between classes.
The class that inherits from another class is called the subclass or derived class, while the
class being inherited from is called the superclass or base class.

Types of Inheritance:

1. Single Inheritance: A subclass inherits from one superclass.

o Example: class Dog(Animal):

2. Multiple Inheritance: A subclass inherits from more than one superclass.

o Example: class Child(Father, Mother):

3. Multilevel Inheritance: A class inherits from a subclass, forming a chain.

o Example: class Animal -> class Mammal -> class Dog

4. Hierarchical Inheritance: Multiple subclasses inherit from a single superclass.

o Example: class Animal -> class Dog, class Cat

5. Hybrid Inheritance: A combination of two or more types of inheritance.


o Example: It may involve both multiple and multilevel inheritance.

Each of these types of inheritance helps developers organize and reuse code efficiently.

2. What are the rules for access specifiers in the Inheritance.

Access specifiers (also known as access modifiers) control the visibility of class members
(attributes and methods) in inheritance. In many object-oriented programming languages
like C++, Java, and Python, access specifiers determine how the members of a class can be
accessed by other classes, especially when inheritance is involved.

Common Access Specifiers:

1. Public:

o Members declared as public are accessible from anywhere (inside or


outside the class, as well as by derived classes).

o In inheritance, public members of the base class remain public in the


derived class.

1.

o cpp

Copy code

class Base {

public:

int x;

};

class Derived : public Base {};

 x will be accessible in both Derived and outside the classes.

2. Protected:

o Members declared as protected are accessible within the class itself and by
derived classes, but not from outside the class.

o In inheritance, protected members of the base class remain protected in


the derived class.

o Example in C++:
cpp

Copy code

class Base {

protected:

int y;

};

class Derived : public Base {};

 y is accessible in Derived, but not outside the class.

3. Private:

o Members declared as private are only accessible within the class in which
they are declared. Derived classes and external classes cannot directly
access private members of the base class.

o However, private members can be accessed indirectly by using public or


protected methods in the base class.

o Example in C++:

cpp

Copy code

class Base {

private:

int z;

};

class Derived : public Base {};

 z is not accessible in Derived or outside the class.

Rules for Access Specifiers in Inheritance:

1. Public Inheritance:

o The public members of the base class remain public in the derived class.

o The protected members of the base class remain protected in the derived
class.

o Private members of the base class remain private and cannot be accessed
directly by the derived class.

2. Protected Inheritance:

o The public and protected members of the base class become protected in
the derived class.

o Private members remain private and inaccessible to the derived class.

3. Private Inheritance:

o All public and protected members of the base class become private in the
derived class.

o Private members remain private and inaccessible.

Example of Access Specifiers in C++ Inheritance:

cpp

Copy code

class Base {

public:

int publicVar;

protected:

int protectedVar;

private:

int privateVar;

};

// Public inheritance

class Derived1 : public Base {

// publicVar remains public

// protectedVar remains protected

// privateVar is not accessible

};
// Protected inheritance

class Derived2 : protected Base {

// publicVar becomes protected

// protectedVar remains protected

// privateVar is not accessible

};

// Private inheritance

class Derived3 : private Base {

// publicVar becomes private

// protectedVar becomes private

// privateVar is not accessible

};

In general, the access control determines how much of the base class is exposed to the
derived class and to the outside world. The derived class can access the base class’s public
and protected members, but cannot access private members directly.

3. Explain multiple Inheritance in detail with syntax and example.

Multiple Inheritance:

Definition: Multiple inheritance is a feature in object-oriented programming where a


subclass can inherit from more than one base class. This allows the subclass to inherit
properties and behaviors from multiple parent classes, offering more flexibility and
reusability in code.

In languages like C++, multiple inheritance is directly supported. However, in some


languages like Java, it is restricted or partially supported using interfaces. The main
challenge of multiple inheritance is dealing with the Diamond Problem, where ambiguity
arises if two base classes have methods or members with the same name.

Syntax of Multiple Inheritance (C++ Example):

In C++, multiple inheritance is implemented by specifying more than one base class,
separated by commas.
cpp

Copy code

class Base1 {

// Members of Base1

};

class Base2 {

// Members of Base2

};

class Derived : public Base1, public Base2 {

// Members of Derived class

};

In this example, the class Derived inherits from both Base1 and Base2. This means Derived
will have access to the members of both base classes.

4. Write a C++ program for displaying CAE 1 result with the help of multilevel Inheritance.
(For result take the average of your 6 subjects).

#include <iostream>

using namespace std;

// Base class: Student

class Student {

protected:

string name;

int rollNo;

public:
void getStudentInfo() {

cout << "Enter student name: ";

cin >> name;

cout << "Enter roll number: ";

cin >> rollNo;

void displayStudentInfo() {

cout << "Name: " << name << endl;

cout << "Roll Number: " << rollNo << endl;

};

// Derived class 1: Marks (inherits Student)

class Marks : public Student {

protected:

float marks[6];

public:

void getMarks() {

cout << "Enter marks for 6 subjects:" << endl;

for (int i = 0; i < 6; i++) {

cout << "Subject " << i + 1 << ": ";

cin >> marks[i];

}
void displayMarks() {

cout << "Marks in 6 subjects:" << endl;

for (int i = 0; i < 6; i++) {

cout << "Subject " << i + 1 << ": " << marks[i] << endl;

};

// Derived class 2: Result (inherits Marks)

class Result : public Marks {

private:

float average;

public:

void calculateAverage() {

float total = 0;

for (int i = 0; i < 6; i++) {

total += marks[i];

average = total / 6;

void displayResult() {

displayStudentInfo();

displayMarks();

cout << "Average Marks: " << average << endl;

}
};

// Main function

int main() {

Result student;

student.getStudentInfo(); // Input student information

student.getMarks(); // Input marks for 6 subjects

student.calculateAverage(); // Calculate the average

student.displayResult(); // Display result including average

return 0; }

5. Write a C++ program to accept employee information from user with data members such
as employee name, employee code and salary of employee. Display the information using
multiple Inheritance.

Here is a C++ program that demonstrates multiple inheritance by accepting employee


information (name, employee code, and salary) from the user and then displaying it. The
program uses multiple classes, where each class represents a part of the employee's
information, and then the derived class combines them.

C++ Program for Employee Information Using Multiple Inheritance

#include <iostream>

using namespace std;

// Base class 1: PersonalDetails

class PersonalDetails {

protected:

string empName;

public:

void getPersonalDetails() {
cout << "Enter employee name: ";

cin >> empName;

void displayPersonalDetails() {

cout << "Employee Name: " << empName << endl;

};

// Base class 2: EmployeeCode

class EmployeeCode {

protected:

int empCode;

public:

void getEmployeeCode() {

cout << "Enter employee code: ";

cin >> empCode;

void displayEmployeeCode() {

cout << "Employee Code: " << empCode << endl;

};

// Derived class: Salary (inherits PersonalDetails and EmployeeCode)

class Salary : public PersonalDetails, public EmployeeCode {


private:

float salary;

public:

void getSalary() {

cout << "Enter employee salary: ";

cin >> salary;

void displaySalary() {

cout << "Salary: $" << salary << endl;

void displayEmployeeInformation() {

displayPersonalDetails();

displayEmployeeCode();

displaySalary();

};

// Main function

int main() {

Salary employee; // Create object of Salary class

// Get employee information

employee.getPersonalDetails();

employee.getEmployeeCode();
employee.getSalary();

// Display employee information

cout << "\nEmployee Information:\n";

employee.displayEmployeeInformation();

return 0;

6. What is ambiguity resolution in multiple Inheritance.

Ambiguity Resolution in Multiple Inheritance:

Ambiguity in multiple inheritance occurs when a derived class inherits from two or more
base classes that have methods or members with the same name. The compiler becomes
confused about which version of the method or member to use when called from the
derived class. This issue is often referred to as the Diamond Problem.

Causes of Ambiguity:

Ambiguity arises when two or more base classes have methods or data members with the
same name, and the derived class does not know which one to use.

Resolving Ambiguity:

There are two main ways to resolve ambiguity in multiple inheritance:

1. Using Scope Resolution Operator (::):

o In the derived class, the ambiguity can be resolved by explicitly specifying


which base class's method or member to use with the scope resolution
operator (::).

2. Virtual Inheritance (for solving the Diamond Problem):

o In cases where multiple inheritance leads to the Diamond Problem (where


a single base class is inherited through multiple paths), virtual inheritance
is used to prevent ambiguity by ensuring that only one copy of the base
class is inherited.

7. Explain Hybrid Inheritance in detail with definition and example.

Definition: Hybrid inheritance is a combination of more than one type of inheritance in a


single program. It usually involves the mix of single, multiple, multilevel, and hierarchical
inheritance. Hybrid inheritance allows for greater flexibility in designing a class hierarchy
by combining different inheritance types to suit specific needs.

Since hybrid inheritance involves multiple inheritance, it may lead to ambiguity issues (like
the Diamond Problem), and programmers may need to resolve these using techniques
such as virtual inheritance.

Types of Inheritance in Hybrid Inheritance:

 Single Inheritance: A class inherits from one base class.

 Multiple Inheritance: A class inherits from more than one base class.

 Multilevel Inheritance: A class inherits from a derived class.

 Hierarchical Inheritance: Multiple classes inherit from a single base class.

#include <iostream>

using namespace std;

// Base class 1: Person (Common for Employee and Student)

class Person {

protected:

string name;

int age;

public:

void getPersonalDetails() {

cout << "Enter name: ";

cin >> name;

cout << "Enter age: ";

cin >> age;

}
void displayPersonalDetails() {

cout << "Name: " << name << endl;

cout << "Age: " << age << endl;

};

// Derived class 1: Employee (inherits from Person)

class Employee : public Person {

protected:

int empID;

float salary;

public:

void getEmployeeDetails() {

cout << "Enter employee ID: ";

cin >> empID;

cout << "Enter salary: ";

cin >> salary;

void displayEmployeeDetails() {

cout << "Employee ID: " << empID << endl;

cout << "Salary: " << salary << endl;

};

// Derived class 2: Student (inherits from Person)


class Student : public Person {

protected:

int studentID;

string course;

public:

void getStudentDetails() {

cout << "Enter student ID: ";

cin >> studentID;

cout << "Enter course: ";

cin >> course;

void displayStudentDetails() {

cout << "Student ID: " << studentID << endl;

cout << "Course: " << course << endl;

};

// Derived class 3: TeachingAssistant (inherits from both Employee and Student)

class TeachingAssistant : public Employee, public Student {

private:

int workHours;

public:

void getTeachingAssistantDetails() {

getPersonalDetails(); // Call from Person class


getEmployeeDetails(); // Call from Employee class

getStudentDetails(); // Call from Student class

cout << "Enter work hours per week: ";

cin >> workHours;

void displayTeachingAssistantDetails() {

displayPersonalDetails(); // Display common personal details

displayEmployeeDetails(); // Display employee details

displayStudentDetails(); // Display student details

cout << "Work Hours per Week: " << workHours << endl;

};

// Main function

int main() {

TeachingAssistant ta; // Create object of TeachingAssistant class

cout << "Enter Teaching Assistant Details:" << endl;

ta.getTeachingAssistantDetails(); // Input details

cout << "\nTeaching Assistant Details:" << endl;

ta.displayTeachingAssistantDetails(); // Display details

return 0;

}
8. Discuss the constructors and destructors in derived classes with code.

Constructors and Destructors in Derived Classes:

In object-oriented programming, constructors and destructors play a crucial role in


initializing and cleaning up objects, respectively. When dealing with inheritance, especially
in derived classes, the order of calling constructors and destructors becomes significant.

Constructors in Derived Classes:

 When an object of a derived class is created, the constructor of the base class is
called first, followed by the constructor of the derived class.

 The base class constructor is responsible for initializing the base class members,
while the derived class constructor initializes the derived class-specific members.

 If no base class constructor is specified in the derived class, the default constructor
of the base class is called.

Destructors in Derived Classes:

 Destructors are called in the reverse order of constructors.

 The derived class destructor is called first, followed by the base class destructor.

 This ensures that resources allocated by the derived class are cleaned up first, and
then the resources of the base class are cleaned up.

Order of Constructor and Destructor Calls:

1. Constructor call order: Base class → Derived class

2. Destructor call order: Derived class → Base class

#include <iostream>

using namespace std;

// Base class

class Base {

public:

// Base class constructor

Base() {

cout << "Base class constructor called" << endl;


}

// Base class destructor

~Base() {

cout << "Base class destructor called" << endl;

};

// Derived class

class Derived : public Base {

public:

// Derived class constructor

Derived() {

cout << "Derived class constructor called" << endl;

// Derived class destructor

~Derived() {

cout << "Derived class destructor called" << endl;

};

// Main function

int main() {

cout << "Creating Derived object" << endl;

Derived obj; // Object of Derived class

cout << "Exiting main" << endl;


return 0;

9. What is the role of early binding and late binding in polymorphism? Justify your answer
with explanations.

Early Binding and Late Binding in Polymorphism

Binding refers to the process of associating a function call to the actual code to be
executed. In the context of polymorphism, there are two types of binding:

1. Early Binding (Static Binding or Compile-time Binding):

o Early binding occurs when the function call is resolved at compile time.

o It is used in cases where the compiler knows at compile time which


function to call based on the type of the object.

o Function overloading and operator overloading are examples where early


binding is used.

o Early binding is associated with compile-time polymorphism, meaning the


function to be invoked is determined before the program is run.

2. Late Binding (Dynamic Binding or Run-time Binding):

o Late binding occurs when the function call is resolved at run time.

o It is used in cases of virtual functions where the actual function to be


invoked depends on the type of the object at run time.

o Late binding is associated with runtime polymorphism, meaning the exact


function to be invoked is determined during the execution of the program,
often involving pointers or references to base classes.

Polymorphism:

Polymorphism allows objects of different types to be treated as objects of a common base


type. It comes in two forms:

1. Compile-time Polymorphism: Achieved using function overloading and operator


overloading. This is linked with early binding.

2. Run-time Polymorphism: Achieved using inheritance and virtual functions. This is


linked with late binding.

Early Binding in Polymorphism:

In early binding (compile-time polymorphism), the compiler knows at compile time which
function to call based on the function signatures or the type of the object. This is done
during function overloading or operator overloading.

Example of Early Binding:

#include <iostream>

using namespace std;

class A {

public:

void display() {

cout << "Display function in Class A" << endl;

};

int main() {

A obj;

obj.display(); // Early binding happens here, resolved at compile time

return 0;

Late Binding in Polymorphism:

Late binding (run-time polymorphism) allows the program to determine which function to
call based on the type of the object at run time. This is typically done using pointers or
references to base classes and virtual functions. Late binding enables the program to
handle objects of different derived classes in a polymorphic manner.

Example of Late Binding:

cpp

Copy code

#include <iostream>

using namespace std;


class Base {

public:

virtual void display() { // Virtual function

cout << "Display function in Base class" << endl;

};

class Derived : public Base {

public:

void display() override { // Overriding base class function

cout << "Display function in Derived class" << endl;

};

int main() {

Base* basePtr; // Pointer to base class

Derived derivedObj;

basePtr = &derivedObj; // Pointing base class pointer to derived class object

basePtr->display(); // Late binding, resolved at run-time

return 0;

Justification of Role in Polymorphism:

1. Early Binding:

o Best suited for compile-time polymorphism, where the function to be


called is known at compile time. It provides better performance as there is
no run-time overhead.
o However, early binding is not flexible enough to handle cases where the
object type is only known at run time, limiting its use in polymorphic
situations.

2. Late Binding:

o Plays a critical role in run-time polymorphism. It allows a program to


behave differently depending on the actual object type at run time, which
is essential for implementing real-world systems where objects might be of
various derived types.

o Virtual functions and late binding enable creating abstract interfaces and
working with object hierarchies in a flexible and extensible manner,
making it the backbone of object-oriented design.

10. Explain Hierarchical Inheritance in detail with definition and example.

Hierarchical Inheritance:

Definition: Hierarchical inheritance is a type of inheritance in which multiple derived (child)


classes inherit from a single base (parent) class. In this type of inheritance, the base class
shares its properties and methods with multiple derived classes, which can extend or
override those properties and methods.

In hierarchical inheritance:

 A common base class acts as the parent for all the derived classes.

 Each derived class can independently have its own unique properties or methods,
in addition to inheriting the characteristics of the base class.

Features:

 Allows code reuse by having common functionality in the base class.

 Promotes consistency, as derived classes inherit a common interface or set of


features from the base class.

 Each derived class can also have its own specific features, thus providing flexibility.

Diagram Representation:

markdown

Copy code

Base Class
/ \

/ \

Derived1 Derived2

Derived3

Here, Derived1, Derived2, and Derived3 are derived from the same Base Class.

Example of Hierarchical Inheritance in C++:

Let's consider an example where we have a base class Animal, and three derived classes
Dog, Cat, and Bird. All of these animals share common properties, such as the ability to
make a sound (inherited from Animal), but each derived class can have its own specific
sound.

Example of

#include <iostream>

using namespace std;

// Base class

class Animal {

public:

void eat() {

cout << "This animal is eating." << endl;

void sleep() {

cout << "This animal is sleeping." << endl;

// Virtual function for making sound

virtual void makeSound() {


cout << "This animal makes a sound." << endl;

};

// Derived class 1: Dog

class Dog : public Animal {

public:

void makeSound() override {

cout << "The dog barks." << endl;

};

// Derived class 2: Cat

class Cat : public Animal {

public:

void makeSound() override {

cout << "The cat meows." << endl;

};

// Derived class 3: Bird

class Bird : public Animal {

public:

void makeSound() override {

cout << "The bird chirps." << endl;

};
// Main function

int main() {

// Creating objects of derived classes

Dog dog;

Cat cat;

Bird bird;

// Calling base class methods from derived class objects

dog.eat();

dog.makeSound();

cat.eat();

cat.makeSound();

bird.eat();

bird.makeSound();

return 0;

Advantages of Hierarchical Inheritance:

1. Code Reusability: Common functionality, like eat() and sleep() in the base class
Animal, can be reused by all the derived classes, reducing redundancy.

2. Extendability: New derived classes can be added without modifying the base class.
For instance, we can add more animals like Fish or Horse without changing the
Animal class.

3. Polymorphism: By using virtual functions, we can take advantage of runtime


polymorphism, allowing different derived classes to have their unique
implementations while sharing a common interface.
Disadvantages:

1. Tight Coupling: The derived classes are tightly coupled to the base class, so if the
base class changes, it may impact all derived classes.

2. Complexity: As the number of derived classes increases, managing and


understanding the hierarchy can become more complex.

Conclusion:

Hierarchical inheritance allows multiple derived classes to share common behavior and
properties from a single base class while also providing the flexibility to have unique
behaviors in each derived class. This structure is useful in scenarios where different objects
share some basic functionality but need to behave differently in specific ways.

Unit-IV

1. Write a difference between compile time polymorphism and runtime polymorphism.

Here’s a detailed comparison between compile-time polymorphism and runtime


polymorphism in programming, particularly in the context of C++:

Aspect Compile-Time Polymorphism Runtime Polymorphism


Also known as static polymorphism, it is Also known as dynamic polymorphism
Definition
resolved during compile time. it is resolved during runtime.
The function to be executed is
The function to be executed is
Method Resolution determined at runtime based on the
determined at compile time.
type of the object.
Achieved through function overloading Achieved through inheritance and
Implementation
and operator overloading. virtual functions.
Slightly slower due to the overhead of
Faster execution since the function
Performance dynamic binding and lookup during
address is known at compile time.
execution.
Less flexible; changes require More flexible; allows for changing
Flexibility
recompilation. behaviors at runtime.
Function overloading, where multiple Virtual functions, where a base class
Example functions have the same name but pointer/reference calls derived class
different parameters. functions.
Requires more memory due to the use
Requires less memory since all function
Memory Usage of virtual tables (vtable) for dynamic
calls are resolved at compile time.
binding.
Useful in scenarios where the number of Useful in scenarios where behaviors
Use Case functions is known and fixed at compile may vary at runtime based on the
time. object type.
Type of Binding Early binding (static binding). Late binding (dynamic binding).
Summary:

 Compile-time polymorphism is about resolving function calls at compile time,


providing better performance but less flexibility. It allows for multiple function
signatures to coexist.

 Runtime polymorphism, on the other hand, enables dynamic decision-making


regarding which function to execute based on the actual object type at runtime,
promoting flexibility and extensibility in code.

2. With the help of syntax describe the new and delete operator.

In C++, the new and delete operators are used for dynamic memory management. They
allow the allocation and deallocation of memory during the program's runtime, enabling
the creation of objects and arrays dynamically. Below is a detailed explanation along with
syntax and examples.

1. The new Operator

The new operator is used to allocate memory for an object or an array of objects on the
heap. When an object is created using new, it returns a pointer to the allocated memory.

Syntax:

 Single object allocation:

cpp

Copy code

TypeName* pointerName = new TypeName;

 Array allocation:

cpp

Copy code

TypeName* pointerName = new TypeName[arraySize];

Example:

cpp

Copy code

#include <iostream>

using namespace std;

class MyClass {
public:

int data;

MyClass(int value) : data(value) {

cout << "Constructor called: " << data << endl;

};

int main() {

// Allocate a single object of MyClass

MyClass* obj = new MyClass(10);

// Access the object's data

cout << "Data: " << obj->data << endl;

// Allocate an array of MyClass objects

MyClass* objArray = new MyClass[3] { MyClass(1), MyClass(2), MyClass(3) };

// Access array elements

for (int i = 0; i < 3; i++) {

cout << "Array element " << i << ": " << (objArray + i)->data << endl;

// Deallocate memory

delete obj; // Free the single object

delete[] objArray; // Free the array

return 0;
}

Output:

yaml

Copy code

Constructor called: 10

Data: 10

Constructor called: 1

Constructor called: 2

Constructor called: 3

Array element 0: 1

Array element 1: 2

Array element 2: 3

2. The delete Operator

The delete operator is used to deallocate memory that was previously allocated using new.
It ensures that the memory is freed and can be reused, preventing memory leaks.

Syntax:

 Single object deallocation:

cpp

Copy code

delete pointerName;

 Array deallocation:

cpp

Copy code

delete[] pointerName;

Example (continued from above):

In the previous example, the delete operator is used as follows:

cpp
Copy code

// Deallocate memory

delete obj; // Free the single object

delete[] objArray; // Free the array

Key Points:

 Always match new with delete and new[] with delete[] to avoid memory leaks.

 Failing to deallocate memory can lead to memory leaks, which can exhaust
available memory over time.

 After using delete, the pointer becomes a dangling pointer (pointing to freed
memory). It's a good practice to set the pointer to nullptr after deletion.

Conclusion:

The new and delete operators are essential for dynamic memory management in C++. They
allow programmers to allocate and deallocate memory as needed, providing flexibility in
memory usage. Proper usage of these operators is crucial to avoid memory leaks and
ensure efficient resource management in C++ programs.

3. What is ‘this’ pointer? Write a C++ program for finding the elder person name among three
persons using this pointer.

he this Pointer in C++

In C++, the this pointer is an implicit pointer that points to the object for which a member
function is called. It is used to access the members (attributes and methods) of the current
object. The this pointer is particularly useful in situations where there is ambiguity
between member variables and parameters, allowing you to distinguish between them.

Key Features of this Pointer:

 Implicit: Automatically available inside non-static member functions.

 Type: The type of this is a constant pointer to the class type (e.g., ClassName*
const this).

 Usage: Helps in returning the current object from a member function, accessing
class members, and chaining member function calls.

Example Program to Find the Elder Person Using this Pointer

#include <iostream>
#include <string>

using namespace std;

class Person {

private:

string name;

int age;

public:

// Constructor

Person(string n, int a) : name(n), age(a) {}

// Method to compare ages and find the elder person

Person* elder(Person* p) {

return (this->age > p->age) ? this : p; // Use 'this' pointer to compare ages

// Method to display person's details

void display() {

cout << "Name: " << name << ", Age: " << age << endl;

};

int main() {

// Create three Person objects

Person person1("Alice", 30);

Person person2("Bob", 25);


Person person3("Charlie", 35);

// Find the elder person among the three

Person* elder1 = person1.elder(&person2);

Person* elderEldest = elder1->elder(&person3);

// Display the elder person's details

cout << "Elder person details: ";

elderEldest->display();

return 0;

4. Explain static member functions in C++ with syntax and example.

Static Member Functions in C++

Static member functions in C++ are functions that belong to the class rather than any
particular object of that class. They can be called without creating an instance of the class.
Static member functions can only access static data members of the class and cannot
access non-static members directly.

Key Features of Static Member Functions:

1. Class Level: Static member functions are associated with the class itself, not with
any specific object.

2. Access: They can access only static data members and other static member
functions. They do not have access to non-static members directly because they do
not have a this pointer.

3. No Object Required: They can be called using the class name without creating an
object of that class.

4. Use Cases: Commonly used for utility functions, maintaining global states, or
counting the number of instances of a class.

Syntax:

cpp
Copy code

class ClassName {

public:

static ReturnType FunctionName(Parameters) {

// Function body

};

Example of Static Member Functions:

In this example, we will create a class Counter that keeps track of the number of instances
created. We will use a static member function to display the count of instances.

cpp

Copy code

#include <iostream>

using namespace std;

class Counter {

private:

static int count; // Static data member to keep track of count

public:

Counter() {

count++; // Increment count whenever a new object is created

// Static member function to display the count

static void displayCount() {

cout << "Number of objects created: " << count << endl;
}

};

// Initialize the static data member

int Counter::count = 0;

int main() {

Counter obj1; // Create first object

Counter obj2; // Create second object

// Call the static member function using the class name

Counter::displayCount(); // Output: Number of objects created: 2

Counter obj3; // Create third object

Counter::displayCount(); // Output: Number of objects created: 3

return 0;

Output:

javascript

Copy code

Number of objects created: 2

Number of objects created: 3

Explanation:

 Static Data Member:

o static int count; is a static data member that keeps track of the number of
Counter objects created.
o It is initialized outside the class with int Counter::count = 0;.

 Constructor:

o The constructor increments the static count variable each time a new
Counter object is created.

 Static Member Function:

o static void displayCount(); is a static member function that displays the


current count of objects.

o It can be called using the class name without needing to create an object.

 Main Function:

o We create two Counter objects, obj1 and obj2, which increments the count
to 2.

o We call Counter::displayCount(); to display the current count.

o A third object, obj3, is created, and the count is updated to 3. We call


displayCount() again to show the updated count.

Conclusion:

Static member functions are useful for operations that pertain to the class as a whole
rather than to individual objects. They help manage shared data and provide functionality
without requiring an instance of the class.

5. Create simple C++ program to access static data members to show the car information
such as Id, Name, Rating for a car.

#include <iostream>

#include <string>

using namespace std;

class Car {

private:

static int idCounter; // Static data member for generating unique car IDs

static int totalCars; // Static data member to keep track of total cars

int carId; // Instance data member for the car ID


string carName; // Instance data member for the car name

float carRating; // Instance data member for the car rating

public:

// Constructor to initialize car details

Car(string name, float rating) {

carId = ++idCounter; // Increment the static ID counter and assign to carId

carName = name;

carRating = rating;

totalCars++; // Increment the total car count

// Static member function to display total cars

static void displayTotalCars() {

cout << "Total cars created: " << totalCars << endl;

// Member function to display car information

void displayCarInfo() {

cout << "Car ID: " << carId << ", Name: " << carName << ", Rating: " << carRating <<
endl;

};

// Initialize static data members

int Car::idCounter = 0;

int Car::totalCars = 0;
int main() {

// Create car objects

Car car1("Toyota Camry", 4.5);

Car car2("Honda Accord", 4.7);

Car car3("Ford Mustang", 4.8);

// Display car information

car1.displayCarInfo();

car2.displayCarInfo();

car3.displayCarInfo();

// Display total number of cars

Car::displayTotalCars();

return 0;

6. What is friend function. Write its advantages and disadvantages.

riend Function in C++

A friend function in C++ is a function that is not a member of a class but has the ability to
access the private and protected members of that class. By declaring a function as a friend,
you allow it to bypass the usual access control rules of the class, enabling it to access
private data directly.

Syntax:

To declare a friend function, you use the friend keyword inside the class definition. Here’s
a simple example:

cpp

Copy code
class ClassName {

private:

int data;

public:

ClassName(int value) : data(value) {}

// Declare friend function

friend void display(ClassName obj);

};

// Friend function definition

void display(ClassName obj) {

cout << "Data: " << obj.data << endl;

Advantages of Friend Functions:

1. Access to Private Data: Friend functions can access the private and protected
members of a class, which is useful for operations that require access to multiple
class members without being part of the class.

2. Enhanced Functionality: They allow for enhanced functionality by enabling


operations between objects of different classes without exposing their private
members through public methods.

3. Operator Overloading: Friend functions are often used in operator overloading to


allow operators to work with user-defined types.

4. Improved Code Organization: They can help keep code organized by allowing non-
member functions to operate on class objects while still having access to their
internals.

Disadvantages of Friend Functions:

1. Breaks Encapsulation: Using friend functions can lead to a violation of


encapsulation principles. By granting access to private data, you can make it easier
for errors to occur or for the internal implementation of a class to be modified
without proper control.

2. Tight Coupling: Friend functions create tight coupling between classes. Changes in
one class may affect the functionality of the friend function, which can lead to
maintenance issues.

3. Less Readable Code: Overuse of friend functions can make code less readable and
harder to understand, as it may not be immediately clear which functions have
access to a class's private members.

4. Limited Use: Since friend functions are not part of the class, they cannot be used
polymorphically, and they do not have access to the this pointer, which limits their
capabilities compared to member functions.

Conclusion:

Friend functions can be powerful tools in C++, providing flexibility and access to private
class members. However, they should be used judiciously, as they can undermine the
principles of encapsulation and lead to tightly coupled code. Proper design should
prioritize maintaining encapsulation and minimizing dependencies between classes when
possible.

7. Explain virtual function and pure virtual function with code.

Virtual Functions in C++

A virtual function is a member function in a base class that you expect to override in
derived classes. When you use a base class pointer or reference to refer to a derived class
object and call a virtual function, the C++ runtime system determines which function to
invoke based on the actual object type, not the type of the pointer or reference. This is
known as dynamic binding or late binding.

Syntax:

To declare a virtual function, use the virtual keyword in the base class.

cpp

Copy code

class Base {

public:

virtual void show() {

cout << "Base class show function called." << endl;


}

};

class Derived : public Base {

public:

void show() override { // override is optional but recommended

cout << "Derived class show function called." << endl;

};

Pure Virtual Functions

A pure virtual function is a virtual function that has no definition in the base class and is
declared by assigning 0 to it. It makes the base class an abstract class, which cannot be
instantiated. Any derived class must provide an implementation for the pure virtual
function to be instantiated.

Syntax:

To declare a pure virtual function, use the = 0 syntax in the base class.

cpp

Copy code

class AbstractBase {

public:

virtual void show() = 0; // Pure virtual function

};

class ConcreteDerived : public AbstractBase {

public:

void show() override {

cout << "ConcreteDerived class show function called." << endl;

}
};

Example Code

Here is a complete example that demonstrates both virtual functions and pure virtual
functions:

cpp

Copy code

#include <iostream>

using namespace std;

// Base class with a virtual function

class Base {

public:

virtual void show() {

cout << "Base class show function called." << endl;

};

// Derived class that overrides the virtual function

class Derived : public Base {

public:

void show() override { // Override the base class function

cout << "Derived class show function called." << endl;

};

// Abstract base class with a pure virtual function

class AbstractBase {
public:

virtual void show() = 0; // Pure virtual function

};

// Derived class that implements the pure virtual function

class ConcreteDerived : public AbstractBase {

public:

void show() override {

cout << "ConcreteDerived class show function called." << endl;

};

int main() {

// Demonstrating virtual functions

Base* b; // Base class pointer

Derived d; // Derived class object

b = &d; // Pointing to derived class object

// Calling show function

b->show(); // Output: Derived class show function called.

// Demonstrating pure virtual functions

AbstractBase* ab; // Abstract base class pointer

ConcreteDerived cd; // ConcreteDerived class object

ab = &cd; // Pointing to ConcreteDerived object

// Calling show function


ab->show(); // Output: ConcreteDerived class show function called.

return 0;

Output:

javascript

Copy code

Derived class show function called.

ConcreteDerived class show function called.

Explanation:

1. Virtual Functions:

o In the Base class, the show() function is declared as virtual.

o The Derived class overrides the show() function.

o In main(), we create a Base class pointer pointing to a Derived object.


When b->show() is called, it executes the show() function of the Derived
class due to dynamic binding.

2. Pure Virtual Functions:

o The AbstractBase class contains a pure virtual function show().

o The ConcreteDerived class implements the pure virtual function.

o In main(), we create an AbstractBase class pointer pointing to a


ConcreteDerived object. Calling ab->show() invokes the show() function of
the ConcreteDerived class.

Conclusion:

Virtual functions and pure virtual functions are essential for achieving polymorphism in C+
+. Virtual functions allow derived classes to provide specific implementations, while pure
virtual functions ensure that derived classes adhere to a specific interface, making the base
class abstract. This mechanism enables dynamic behavior and flexibility in object-oriented
design.

8. Create two classes DM And DB where DM has data members as meter and centimeters
whereas DB stores distances in feet and inches. Carry out addition operations using friend
function.

Here's a C++ program that defines two classes, DM (for distances in meters and
centimeters) and DB (for distances in feet and inches). We will implement a friend function
to perform addition operations between these two classes, converting the distances
appropriately.

C++ Program for Adding Distances Using Friend Function

cpp

Copy code

#include <iostream>

using namespace std;

// Class for distance in meters and centimeters

class DM {

private:

float meters; // Distance in meters

float centimeters; // Distance in centimeters

public:

// Constructor

DM(float m, float cm) : meters(m), centimeters(cm) {}

// Friend function to add DM and DB objects

friend void addDistances(DM d1, DB d2);

// Function to display distance in meters and centimeters

void display() {

cout << "Distance in DM: " << meters << " meters and " << centimeters << "
centimeters." << endl;
}

};

// Class for distance in feet and inches

class DB {

private:

float feet; // Distance in feet

float inches; // Distance in inches

public:

// Constructor

DB(float f, float in) : feet(f), inches(in) {}

// Friend function to add DM and DB objects

friend void addDistances(DM d1, DB d2);

// Function to display distance in feet and inches

void display() {

cout << "Distance in DB: " << feet << " feet and " << inches << " inches." << endl;

};

// Function to add distances from DM and DB

void addDistances(DM d1, DB d2) {

// Convert DM to feet and inches

float totalMeters = d1.meters + d1.centimeters / 100; // Convert cm to m

float totalFeet = totalMeters * 3.28084; // Convert meters to feet


int feetPart = static_cast<int>(totalFeet);

float inchesPart = (totalFeet - feetPart) * 12; // Convert decimal feet to inches

// Add DB distances

float finalFeet = feetPart + d2.feet;

float finalInches = inchesPart + d2.inches;

// Normalize inches to feet

if (finalInches >= 12) {

finalFeet += static_cast<int>(finalInches / 12);

finalInches = static_cast<int>(finalInches) % 12; // Get remaining inches

// Display the result

cout << "Total Distance: " << finalFeet << " feet and " << finalInches << " inches." << endl;

int main() {

// Create DM and DB objects

DM distance1(2, 50); // 2 meters and 50 centimeters

DB distance2(6, 8); // 6 feet and 8 inches

// Display individual distances

distance1.display();

distance2.display();

// Add the distances


addDistances(distance1, distance2);

return 0;

Output:

yaml

Copy code

Distance in DM: 2 meters and 50 centimeters.

Distance in DB: 6 feet and 8 inches.

Total Distance: 9 feet and 4.30699 inches.

Explanation:

1. Class DM:

o Contains private data members meters and centimeters to store distances


in metric units.

o A constructor initializes these members.

o A member function display() prints the distance in meters and centimeters.

2. Class DB:

o Contains private data members feet and inches to store distances in


imperial units.

o A constructor initializes these members.

o A member function display() prints the distance in feet and inches.

3. Friend Function addDistances:

o Takes two parameters, one of type DM and one of type DB.

o Converts the distance from the DM object to feet and inches.

o Adds the feet and inches from the DB object.

o Normalizes the total inches if they exceed 12 (converting excess inches to


feet).

4. Main Function:
o Creates an instance of DM with 2 meters and 50 centimeters.

o Creates an instance of DB with 6 feet and 8 inches.

o Displays both distances and calls the addDistances function to compute


and print the total distance.

Conclusion:

This program effectively demonstrates how to use friend functions to perform operations
on different classes while maintaining encapsulation. The program also includes
conversions between metric and imperial units.

4o mini

9. Illustrate the use of pointer to object with example.

In C++, a pointer to an object allows you to point to an instance of a class and manipulate it
through the pointer. This can be useful for dynamic memory allocation, passing objects to
functions without copying them, and managing polymorphism through base class pointers
to derived class objects.

Example: Pointer to Object

Below is a simple example that illustrates the use of pointers to objects in C++. In this
example, we define a class Box that represents a box with width, height, and depth. We
will create a pointer to a Box object and manipulate it.

cpp

Copy code

#include <iostream>

using namespace std;

class Box {

private:

double width;

double height;

double depth;
public:

// Constructor to initialize the box dimensions

Box(double w, double h, double d) : width(w), height(h), depth(d) {}

// Function to calculate volume

double volume() {

return width * height * depth;

// Function to display box dimensions

void displayDimensions() {

cout << "Width: " << width << ", Height: " << height << ", Depth: " << depth << endl;

};

int main() {

// Create a pointer to Box

Box* boxPtr;

// Dynamically allocate memory for a Box object

boxPtr = new Box(3.5, 2.0, 1.5);

// Display dimensions using the pointer

boxPtr->displayDimensions(); // Output: Width: 3.5, Height: 2, Depth: 1.5

// Calculate and display volume using the pointer

cout << "Volume of the box: " << boxPtr->volume() << endl; // Output: Volume of the
box: 10.5

// Deallocate memory

delete boxPtr;

return 0;

Output:

less

Copy code

Width: 3.5, Height: 2, Depth: 1.5

Volume of the box: 10.5

Explanation:

1. Class Definition:

o The Box class contains private data members width, height, and depth.

o The constructor initializes these dimensions.

o The volume() function calculates and returns the volume of the box.

o The displayDimensions() function prints the dimensions of the box.

2. Pointer Declaration:

o In the main() function, we declare a pointer Box* boxPtr; that will point to
a Box object.

3. Dynamic Memory Allocation:

o We dynamically allocate memory for a Box object using new Box(3.5, 2.0,
1.5);.

o This allows us to create an object whose lifetime is managed manually and


can be accessed via the pointer.

4. Using the Pointer:

o We call the displayDimensions() and volume() functions using the pointer


with the -> operator, which allows access to the members of the object the
pointer points to.

5. Memory Deallocation:

o After we're done using the Box object, we deallocate the memory using
delete boxPtr; to avoid memory leaks.

Conclusion:

Pointers to objects in C++ provide flexibility in managing memory and allow for
polymorphic behavior when working with base and derived classes. They enable you to
manipulate object instances without copying them, making it efficient to manage
resources in programs.

4o mini

10. Create a simple code for accessing static data member functions with the help of class
name and class object.

Here's a simple C++ program that demonstrates how to access static data members and
static member functions using both the class name and an object of the class.

C++ Program to Access Static Data Members and Functions

cpp

Copy code

#include <iostream>

using namespace std;

class Counter {

private:

static int count; // Static data member to keep track of count

public:

// Constructor increments count whenever a new object is created

Counter() {

count++;
}

// Static member function to get the current count

static int getCount() {

return count;

// Static member function to reset count

static void resetCount() {

count = 0;

};

// Initialize static data member

int Counter::count = 0;

int main() {

// Access static member function using class name

cout << "Initial Count: " << Counter::getCount() << endl; // Output: 0

// Create objects of Counter class

Counter c1;

Counter c2;

// Access static member function using class name

cout << "Count after creating two objects: " << Counter::getCount() << endl; // Output: 2
// Access static member function using an object

Counter c3;

cout << "Count accessed via object: " << c3.getCount() << endl; // Output: 3

// Reset count using class name

Counter::resetCount();

cout << "Count after reset: " << Counter::getCount() << endl; // Output: 0

return 0;

Output:

mathematica

Copy code

Initial Count: 0

Count after creating two objects: 2

Count accessed via object: 3

Count after reset: 0

Explanation:

1. Class Definition:

o The Counter class contains a private static data member count, which
keeps track of the number of Counter objects created.

o The constructor increments the count each time a new object is


instantiated.

o The static member function getCount() returns the current value of count.

o The static member function resetCount() resets the count to zero.

2. Static Data Member Initialization:

o The static member count is initialized outside the class definition.

3. Main Function:
o The program first accesses the static member function getCount() using the
class name to display the initial count.

o After creating two Counter objects, it again accesses getCount() to show


the updated count.

o Then, it creates a third object and accesses the count using an object of the
class (c3.getCount()).

o Finally, it resets the count using the static function called through the class
name.

Conclusion:

This program demonstrates how to define and use static data members and functions in C+
+. Static members belong to the class rather than any instance, allowing them to be
accessed without creating an object and also through instances of the class.

Thank you

You might also like