Module - 1
Module - 1
Table of contents
Objectives
The objectives of this Module are to:
Understand the software life cycle and various software development phases. Learn the fundamentals of C++ classes and object-oriented design
(OOD) principles. Explore inheritance, polymorphism, and templates to create reusable and modular code. Master the use of pointers and pointer
variables in C++. Understand the relationship between classes and pointers, including inheritance pointers and virtual functions. Learn about
abstract classes and pure virtual functions. Implement array-based lists and manage dynamic memory.
Learning outcome
On completion of this Module, you will be able to:
Understand the software life cycle, software development phases
Apply object-oriented design principles using C++ classes.
Effectively use pointers and array-based lists, and understand their applications in dynamic memory management and class relationships
Session :1
Software Life Cycle, Software Development Phase, Classes: Constructors, Unified Modelling Language Diagrams, Variable (Object) Declaration, Accessing Class Members,
Implementation of Member Functions,
int main() {
Car my_car;
my_car.make ="BMW";
my_car.model = "A100";
cout << my_car.make << endl; // Output: "Toyota"
return 0;
}
4. Constructors:
A constructor is a special method within
a class that initializes object instances Example :
#include <iostream>
when they are created. using namespace std;
Key points: class Car {
public:
❖ Purpose: Constructors set initial values for the
string make;
object’s attributes.
string model;
❖ Name: Constructors have the same name as the
class (usually __init__ in Python). // Constructor
❖ Parameters: The constructor takes parameters (often Car(string make, string model){
including self as the first parameter) to assign this->make = make;
values to attributes. this->model = model;
}
};
int main() {
Car my_car("Toyota", "Camry");
return 0;
}
5. Unified Modeling Language (UML) Diagrams:
What is UML?
o Unified Modeling Language (UML) is a standardized visual modeling language used in
software engineering.
o Its purpose is to provide a general-purpose, intuitive way to visualize system designs.
o UML helps specify, visualize, construct, and document software artifacts.
o It’s not a programming language; rather, it’s a visual language for modeling systems.
Why do we need UML?
o Complex applications involve collaboration among multiple teams, requiring clear
communication.
o UML allows us to communicate system requirements, functionalities, and processes
effectively.
o It saves time by visualizing processes, user interactions, and system structures.
Types of UML Diagrams:
UML includes various diagram types. Let’s focus on class diagrams:
o Class Diagrams: These depict the static structure of a system by showing classes,
their attributes, and methods.
o Class diagrams help identify relationships between different classes or objects.
Elements in Class Diagrams:
o Classes: Represent entities (e.g., “Account,” “Customer”) with attributes and methods.
o Attributes: Describe properties of classes (e.g., “balance” for an Account).
o Methods: Define behavior or actions (e.g., “withdraw()” for an Account).
o Associations: Show logical connections between classes (e.g., “Account” and
“Customer”).
o Relationships: Describe how classes interact.
Common Relationships in Class Diagrams:
o Association: Broad term for any logical connection between classes.
o Directed Association: Represents a directional relationship (e.g., “passenger” and
“airline”).
o Reflexive Association: When a class has multiple functions or responsibilities (e.g.,
staff roles at an airport).
o Multiplicity: Depicts cardinality (e.g., one fleet has multiple airplanes).
o Aggregation: Forms a class from aggregated components (e.g., “library” composed of
books).
o Composition: Similar to aggregation but emphasizes strong dependence (e.g., shoulder
bag and its pocket).
Example: Banking System Class Diagram:
Let’s create a simple class diagram for a banking system:
Classes: “Account,” “Customer”
Attributes: “Account” has “balance,” “Customer” has “name”
Methods: “Account” has “withdraw()” and “deposit()”
Associations: “Account” associated with “Customer”
UML class diagrams provide a powerful way to visualize & communicate system designs
6. Variable (Object) Declaration: in the context of class objects:
Class Objects:
o After defining a class, you can declare variables of that class type.
o In C++ terminology, a class variable is often called a class object or class instance.
o For simplicity, we’ll use the term object to refer to a class variable.
o An object holds an instance of the class, allowing you to work with its properties and
methods.
Syntax for Object Declaration:
o To declare an object that invokes the default constructor, use this syntax:
o className classObjectName;
Example:
clockType myClock; // Creates an object of type clockType
The default constructor initializes instance variables to their default values (usually 0).
Avoid Empty Parentheses: If you want the default constructor to execute, omit the empty
parentheses after the object name. Including empty parentheses accidentally results in a
syntax error.
// Incorrect: Generates a syntax error
clockType myClock(); // Illegal object declaration
Parameterized Constructors:
A class can have two types of constructors:
▪ Default constructor: Executes when you create an object without passing any
arguments.
▪ Constructors with parameters: Execute when you provide specific arguments
during object creation.
When you declare a class object, either the default constructor or a parameterized
constructor executes.
To declare an object that invokes a constructor with parameters, use this syntax:
className classObjectName(argument1, argument2, ...);
▪ Each argument can be a variable or an expression.
Understanding object declaration is crucial for working with class instances!
#include <iostream>
class ClockType {
public:
// Default constructor
ClockType() {
hours = 0;
minutes = 0;
}
// Parameterized constructor
ClockType(int h, int m) {
hours = h;
minutes = m;
}
void displayTime() {
std::cout << "Time: " << hours << ":" << minutes << std::endl;
}
private:
int hours;
int minutes;
};
int main() {
// Declare an object using the default constructor
ClockType myClock1;
myClock1.displayTime(); // Output: Time: 0:0
// Declare an object using the parameterized constructor
ClockType myClock2(10, 30);
myClock2.displayTime(); // Output: Time: 10:30
return 0;
}
In this example:`myClock1` is an object created using the default constructor, which initializes
hours and minutes to 0. `myClock2` is an object created using the parameterized constructor
with values 10 and 30 for hours and minutes, respectively.
7. Accessing Class Members:
In C++, you can access the attributes (data members) and methods (member functions) of a
class using the dot notation. This is done through an instance of the class, known as an
object.
Dot Notation: Used for accessing members through an object.
Arrow Operator (->): Used for accessing members through a pointer to an object.
Scope Resolution Operator (::): Used for accessing static members of a class.
Dot Notation
Syntax: object.attribute or object.method()
Example: If you have an object my_car of a class Car, you can call its method start_engine()
using my_car.start_engine().
Example Code
#include <iostream>
using namespace std;
class Car {
public:
string brand;
void start_engine() {
cout << "Engine started!" << endl;
}
};
int main() {
Car my_car;
my_car.brand = "Toyota";
my_car.start_engine(); // Calls the start_engine() method
// Accesses the brand attribute
cout << "Brand: " << my_car.brand << endl;
return 0;
}
Accessing Members via Pointers
When you have a pointer to an object, you use the arrow operator (->) to access its members.
Syntax: pointer->attribute or pointer->method()
Example:
Car* car_ptr = &my_car;
car_ptr->start_engine(); // Calls the start_engine() method via pointer
// Accesses the brand attribute via pointer
cout << "Brand: " << car_ptr->brand << endl;
Static Members
Static members belong to the class rather than any object instance. You access them using
the scope resolution operator (::).
Syntax: ClassName::static_member
Example:
class Car {
public:
static int total_cars;
static void show_total_cars() {
cout << "Total cars: " << total_cars << endl;
}
};
int Car::total_cars = 0;
int main() {
Car::total_cars = 5;
Car::show_total_cars(); // Calls the static method
return 0;
}
8. Implementation of Member Functions:
Member functions define the behavior of a class. They allow objects to perform specific
tasks or manipulate their internal state.
Implementation within the Class Definition:
Member functions can be implemented directly within the class definition.
Example:
class Rectangle {
private:
double length;
double width;
public:
// Member function implemented within the class definition
double calculate_area() {
return length * width;
}
};
Implementation Outside the Class Definition:
Member functions can also be implemented outside the class definition using the scope
resolution operator ::.
Example:
class Rectangle {
private:
double length;
double width;
public:
double calculate_area(); // Declaration of the member function
};
// Implementation of the member function outside the class
double Rectangle::calculate_area() {
return length * width;
}
Access Specifiers:
Member functions can be declared in different sections of the class: public, private, or
protected.
Public member functions can be accessed from outside the class.
Private member functions can only be accessed from within the class.
Protected member functions can be accessed from within the class and by derived classes.
Example: Implementing a calculate_area() Method in a Rectangle Class:
Let’s consider a Rectangle class that has a length and width. We want to calculate the area
of the rectangle.
Here is a complete example:
#include <iostream>
class Rectangle {
private:
double length;
double width;
public:
Rectangle(double l, double w) : length(l), width(w) {}
Viva Questions:
1. Can you explain the different phases of the software life cycle and their importance?
2. How does user feedback influence the maintenance phase of the software life cycle?
3. What are the key activities involved in the requirements analysis phase of the SDLC?
4. How do you ensure that the design phase aligns with the requirements gathered?
5. What is a constructor in object-oriented programming, and why is it important?
6. Can you provide an example of a parameterized constructor and explain its use?
7. What are the different types of UML diagrams, and what purpose does each serve?
8. How do UML diagrams help in the software development process?
9. How do you declare an object in C++ or Python? Provide an example.
10. What is the difference between declaring a variable and initializing it?
11. How do you access public and private members of a class in C++?
12. Can you explain the concept of encapsulation with an example?
Theory Questions:
1. Describe the phases of the software life cycle with examples. How does each phase
contribute to the overall success of the software?
2. Explain the importance of the design phase in the SDLC. What are the key
deliverables produced during this phase?
3. Discuss the role of constructors in object-oriented programming. How do they differ
from regular methods?
4. What are UML diagrams, and why are they used in software engineering? Provide
examples of at least two types of UML diagrams.
5. Explain the process of declaring and initializing and accessing attributes of a
class/object in C++.
6. Describe the process of implementing member functions in a class. Provide an
example in C++.
Session :2
Reference Parameters and Class Objects (Variables), Assignment Operator and Classes, Class Scope, Functions and Classes, Constructors and Default Parameters,
Destructors, Structs
1. Reference Parameters and Class Objects (Variables):
Pass by Value:
When a variable is passed by value to a function, a copy of the variable’s value is made and
passed to the function. This means that any changes made to the parameter inside the
function do not affect the original variable.
Key Points:
❖ A copy of the variable is passed.
❖ Changes made inside the function do not affect the original variable.
❖ Commonly used for primitive data types like integers, floats, and characters.
Pass by Reference:
When a variable is passed by reference to a function, the function receives a reference to the
original variable. This means that any changes made to the parameter inside the function
will affect the original variable.
Key Points:
❖ A reference to the variable is passed.
❖ Changes made inside the function affect the original variable.
❖ Commonly used for objects and large data structures to avoid copying overhead.
Passing object as Reference:
When you pass a class object as a parameter to a function, it is passed by reference. This
means that the function receives a reference to the original object, not a copy of it. As a
result, any changes made to the object within the function will affect the original object. This
is different from passing primitive data types (like integers or floats), which are typically
passed by value, meaning a copy of the data is passed to the function.
Key Points:
❖ Pass by Reference: When a class object is passed to a function, the function operates on the original object.
No new copy of the object is created, which can save memory and processing time.
❖ Effect on Original Object: Any modifications made to the object within the function will reflect on the original
object. This is useful for functions that need to update or modify the state of an object.
Example:
Let’s consider a Person class with an attribute address. We will create a function that
updates the address of a Person object.
#include <iostream>
using namespace std;
class Person {
public:
string name;
string address;
Person(string n, string a) : name(n), address(a) {}
void display() {
cout << "Name: " << name << ", Address: " << address << endl;
}
};
// Function to update the address of a Person object
void updateAddress(Person &p, string newAddress) {
p.address = newAddress;
}
int main() {
Person person1("John Doe", "123 Main St");
person1.display();
// Update the address using the function
updateAddress(person1, "456 Cross St");
person1.display(); // The address should now be updated
return 0;
}
Example:
Let’s consider a Car class and demonstrate how the assignment operator works with objects.
#include <iostream>
using namespace std;
class Car {
public:
string make;
string model;
Car(string m, string mo) : make(m), model(mo) {}
void display() {
cout << "Car: " << make << " " << model << endl;
}
};
int main() {
// Create an instance of Car
Car my_car("Toyota", "Corolla");
my_car.display();
// Assign new_car to reference the same my_car object
Car &new_car = my_car;
new_car.display();
// Modify the new_car object
new_car.model = "Camry";
// Both references reflect the change
my_car.display();
new_car.display();
return 0;
}
Output: Car: Toyota Corolla; Car: Toyota Corolla; Car: Toyota Camry; Car: Toyota Camry
Explanation of the Example:
❖ Class Definition: The Car class has a constructor to initialize make and model
attributes. It has a display method to print these attributes.
❖ Object Creation: A Car object my_car is created with the make “Toyota” and model
“Corolla”. The display method is called to show the initial state of my_car.
❖ Assignment: The new_car reference is assigned to reference the same my_car object
using the assignment operator (=). The display method is called on new_car to show
that it references the same object.
❖ Modification: The model attribute of new_car is changed to “Camry”. Both my_car
and new_car reflect this change because they reference the same object.
By understanding how the assignment operator works with objects, you can effectively
manage object references and ensure that your programs behave as expected when
sharing and modifying objects.
3. Class Scope:
Class scope refers to the visibility and accessibility of class members (attributes and
methods) within a class. In C++, access levels control how these members can be accessed
from outside the class. The three primary access levels are public, private, and protected.
Key Points:
❖ Public Access: Members declared as public can be accessed from anywhere in the program. Public members
are accessible both inside and outside the class.
❖ Private Access: Members declared as private can only be accessed within the class itself. Private members
are not accessible from outside the class, ensuring encapsulation.
❖ Protected Access: Members declared as protected can be accessed within the class and by derived classes.
Protected members are not accessible from outside the class, but they can be accessed by subclasses.
Example:
Let’s consider a simple Car class to demonstrate these access levels.
#include <iostream>
using namespace std;
class Car {
public:
string make; // Public attribute
void display() { // Public method
cout << "Car make: " << make << endl;
cout << "Car model: " << model << endl;
}
private:
string model; // Private attribute
protected:
int year; // Protected attribute
};
int main() {
Car myCar;
myCar.make = "Toyota"; // Accessible
// myCar.model = "Corolla"; // Error: 'model' is private
// myCar.year = 2020; // Error: 'year' is protected
myCar.display(); // Accessible
return 0;
}
Explanation of the Example:
❖ Public Attribute and Method: The make attribute and display method are declared as
public, so they can be accessed from outside the class. In the main function, myCar.make
is assigned a value, and myCar.display() is called without any issues.
❖ Private Attribute: The model attribute is declared as private, so it cannot be accessed
directly from outside the class.Attempting to assign a value to myCar.model in the main
function results in a compilation error.
❖ Protected Attribute: The year attribute is declared as protected, so it cannot be accessed
directly from outside the class. Attempting to assign a value to myCar.year in the main
function results in a compilation error. However, year can be accessed by derived classes.
By understanding class scope and access levels, you can effectively control the visibility and
accessibility of class members, ensuring proper encapsulation and inheritance in your
programs.
void display() {
cout << "Car make: " << make << ", model: " << model << endl;
}
};
int main() {
// Creating objects with and without parameters
Car car1; // Uses default parameters
Car car2("Toyota"); // Uses default for model
Car car3("Honda", "Civic"); // Provides both parameters
car1.display();
car2.display();
car3.display();
return 0;
}
Output:
Car make: Unknown, model: Unknown
Car make: Toyota, model: Unknown
Car make: Honda, model: Civic
Explanation of the Example:
❖ Constructor with Default Parameters: The Car class constructor has two parameters,
make and model, both with default values “Unknown”. If no arguments are provided,
the default values are used.
❖ Object Creation: car1 is created without any arguments, so it uses the default values.
car2 is created with only the make argument, so model uses the default value. car3 is
created with both make and model arguments, so no default values are used.
❖ Display Method: The display method prints the make and model of the car. The output
shows how the default parameters are used when arguments are not provided.
By using constructors with default parameters, you can provide flexibility in object creation,
allowing for both default and customized initialization of objects.
6. Destructors:
Destructors: Destructors are special member functions in a class that are called
automatically when an object is destroyed.Their primary purpose is to clean up resources
that the object may have acquired during its lifetime, such as memory, file handles, or
network connections.In C++, destructors have the same name as the class, prefixed with a
tilde (~).
Key Points:
❖ Automatic Invocation: Destructors are called automatically when an object goes out of scope or is explicitly
deleted. This ensures that resources are released properly without requiring explicit calls.
❖ Resource Management: Destructors are crucial for managing resources, especially in languages like C++
that do not have automatic garbage collection. They help prevent resource leaks by ensuring that resources
are freed when they are no longer needed.
❖ Syntax: Destructors do not take parameters and do not return values. Example syntax: ~ClassName() { /*
cleanup code */ }
Example: Let’s consider a simple Example class that demonstrates the use of a
destructor.
#include <iostream>
using namespace std;
class Example {
public:
// Constructor
Example() {
cout << "Constructor called." << endl;
}
// Destructor
~Example() {
cout << "Destructor called." << endl;
}
};
int main() {
{
Example ex;
// Object ex is created and constructor is called
} // Destructor is called automatically here when ex goes out of scope
return 0;
}
Output:
Constructor called.
Destructor called.
Explanation of the Example:
❖ Constructor: The Example class constructor prints a message when an object is created.
❖ Destructor: The Example class destructor prints a message when an object is destroyed.
❖ Automatic Invocation: In the main function, an Example object ex is created within a
block. When the block ends, ex goes out of scope, and the destructor is called
automatically, printing the message.
By using destructors, you can ensure that resources are properly managed and released,
preventing resource leaks and ensuring efficient use of system resources
7. Structs:
• Structs vs. Classes: Structs are similar to classes in that they can contain multiple data
members. However, structs are typically used for lightweight data structures that do not
require the full functionality of classes. Structs do not support inheritance or methods,
making them simpler and more efficient for certain use cases.
Key Points:
❖ Lightweight Data Structures: Structs are ideal for simple data structures that group related data together.
They are often used for small, immutable data types.
❖ No Inheritance or Methods: Structs do not support inheritance, meaning they cannot be extended or
derived from other structs or classes. They also do not support member functions (methods), focusing solely
on data storage.
❖ Default Public Access: In C++, members of a struct are public by default, unlike classes where members
are private by default.
Example: Let’s consider a simple Point struct that represents a point in 2D space with x and
y coordinates.
#include <iostream>
using namespace std;
struct Point {
int x;
int y;
};
int main() {
Point p1;
p1.x = 10;
p1.y = 20;
cout << "Point coordinates: (" << p1.x << ", " << p1.y << ")" << endl;
return 0;
}
Viva Questions
1. What is a reference parameter and how does it differ from a value parameter?
2. How do reference parameters help in modifying the original data of an object?
3. Can you explain with an example how a class object is passed as a reference
parameter to a function?
4. What are the advantages of using reference parameters in functions?
5. How does passing an object by reference affect the performance of a program?
6. What happens if you try to modify a constant reference parameter?
7. What is the purpose of the assignment operator in C++?
8. How do you overload the assignment operator for a class?
9. What is the difference between shallow copy and deep copy in the context of the
assignment operator?
10. What issues can arise if the assignment operator is not properly overloaded?
11. How does the assignment operator differ from the copy constructor?
12. What is class scope and how does it affect the visibility of class members?
13. Explain the difference between public, private, and protected access specifiers.
14. How does class scope help in encapsulation?
15. Can you give an example of how a private member of a class is accessed?
16. What is the significance of the friend keyword in relation to class scope?
17. How does inheritance affect the scope of class members?
18. What is the difference between a global function and a class method?
19. How do methods within a class operate on class attributes?
20. How do you call a method of a class from an object?
21. How can you define a function outside the class definition?
22. What is a constructor and what is its primary purpose?
23. How do default parameters in constructors provide flexibility in object creation?
24. What is the difference between a default constructor and a parameterized constructor?
25. How does constructor overloading work in C++?
26. What happens if you do not define a constructor in a class?
27. What is a destructor and when is it called?
28. Can you explain the purpose of a destructor with an example?
29. How do destructors help in resource management?
30. What is the syntax for defining a destructor in C++?
31. What happens if a destructor is not defined in a class?
32. How do destructors differ from constructors?
33. What is a struct and how is it different from a class?
34. Can you provide an example of a simple struct in C++?
35. Why are structs typically used for lightweight data structures?
36. How do you access members of a struct?
37. What are the limitations of structs compared to classes?
38. Can structs contain methods in C++?
Theory Questions
1. Explain the concept of reference parameters and their advantages in C++ with an
example.
2. Discuss how passing objects by reference can improve the efficiency of a program.
3. Describe the process of overloading the assignment operator in C++. Provide an
example.
4. Explain the difference between shallow copy and deep copy in the context of the
assignment operator.
5. Define class scope and explain the significance of public, private, and protected access
specifiers with examples.
6. Discuss how class scope contributes to encapsulation in object-oriented programming.
7. Compare and contrast global functions and class methods in C++. Provide examples.
8. Explain how methods within a class operate on class attributes and modify the state
of an object.
9. What are constructors in C++? Explain the role of default parameters in constructors
with an example.
10. Discuss the differences between default constructors and parameterized constructors.
11. What is a destructor in C++? Explain its purpose and provide an example.
12. Discuss the importance of destructors in resource management and how they differ
from constructors.
13. Define structs in C++ and explain their typical use cases. Provide an example of a
simple struct.
14. Compare structs and classes in C++, highlighting their differences and limitations.
Session :3
Inheritance: Overriding Member Functions of the Base Class, Constructors of Derived and Base Classes, Header File of a Derived Class, Multiple Inclusions of a Header
File,
1. Overriding Member Functions of the Base Class
Overriding Member Functions:
o In C++, a derived class can override a member function of its base class.
o This means the derived class provides its own implementation of the function, which
replaces the base class’s version when called on an object of the derived class.
o To override a function, the derived class function must have the same signature as the
base class function.
Key Points:
❖ Function Signature: The overridden function in the derived class must have the same name and
parameters as the function in the base class.
❖ Polymorphism: Overriding is a key feature of polymorphism, allowing derived classes to provide specific
implementations of base class functions.
Example:
#include <iostream>
using namespace std;
class Base {
public:
void identify() const {
cout << "Base::identify()" << endl;
}
};
class Derived : public Base {
public:
void identify() const {
cout << "Derived::identify()" << endl;
}
};
int main() {
Base base;
Derived derived;
base.identify(); // Output: Base::identify()
derived.identify(); // Output: Derived::identify()
return 0;
}
class MyClass {
public:
void doSomething();
};
#endif // MYCLASS_H
Pragma Once:
#pragma once
class MyClass {
public:
void doSomething();
};
Key Points:
❖ Include Guards: Use #ifndef, #define, and #endif to prevent multiple inclusions.
❖ Pragma Once: #pragma once is a simpler, non-standard alternative to include guards that achieves the
same effect.
By understanding these principles, you can effectively manage inheritance, constructors, and
header files in C++ to create robust and maintainable code.
Viva Questions
o What is function overriding in C++ and how does it differ from function overloading?
o Can you explain with an example how a derived class can override a member function
of its base class?
o What is the significance of the virtual keyword in function overriding?
o How does the compiler determine which function to call when a function is
overridden?
o What happens if a derived class does not override a virtual function from the base
class?
o How can you call a base class function from a derived class if it has been overridden?
o Explain the order of constructor calls in a derived class and its base class.
o How do you pass arguments to a base class constructor from a derived class
constructor?
o What is the purpose of the initialization list in constructors, especially in the context
of inheritance?
o Can you provide an example where both base and derived class constructors are
called?
o What happens if a base class constructor requires parameters but the derived class
constructor does not provide them?
o How does the destructor call order differ from the constructor call order in
inheritance?
o Why is it important to include the base class header file in the derived class header
file?
o What are include guards and why are they used in header files?
o Can you explain the structure of a derived class header file with an example?
o How do you ensure that a header file is included only once in a program?
o What is the purpose of the #include directive in C++?
o How do you handle dependencies between multiple header files in a large project?
o What problems can arise from multiple inclusions of the same header file?
o How do include guards prevent multiple inclusions of a header file?
o Can you explain the syntax and usage of include guards with an example?
o What is #pragma once and how does it differ from traditional include guards?
o Are there any situations where #pragma once might not be supported?
o How do you decide whether to use include guards or #pragma once in your projects?
Theory Questions
o Define function overriding in C++ and discuss its importance in object-oriented
programming. Provide an example.
o Explain the role of the virtual keyword in function overriding and how it affects
polymorphism.
o Describe the order of constructor and destructor calls in a class hierarchy. Provide an
example to illustrate your explanation.
o Discuss the use of initialization lists in constructors, particularly in the context of
inheritance. Provide an example.
o Explain the structure of a derived class header file and the importance of including the
base class header file. Provide an example.
o Discuss the purpose and implementation of include guards in C++ header files.
Provide an example.
o What are the potential issues caused by multiple inclusions of the same header file?
How can these issues be prevented?
o Compare and contrast include guards and #pragma once as methods to prevent
multiple inclusions of header files. Provide examples of each.
Session :4
Protected Members of a Class, Inheritance as public, protected, or private, Polymorphism: Why Operator Overloading Is Needed, Syntax for Operator Functions,
1. Protected Members of a Class
Protected members in a class are similar to private members but with one key difference: they
can be accessed by derived classes. This access specifier is particularly useful in inheritance.
Key Points:
❖ Protected members are accessible within the class itself and by derived classes. They are not accessible from
outside the class.
Example:
#include <iostream>
using namespace std;
class Parent {
protected:
int id_protected;
};
class Child : public Parent {
public:
void setId(int id) {
id_protected = id; // Accessible here
}
void displayId() {
cout << "id_protected is: " << id_protected << endl;
}
};
int main() {
Child obj;
obj.setId(81);
obj.displayId(); // Output: id_protected is: 81
return 0;
}
void print() {
cout << real << " + i" << imag << endl;
}
};
int main() {
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2; // Using overloaded +
c3.print(); // Output: 12 + i9
return 0;
}
int main() {
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2; // Using overloaded +
c3.print(); // Output: 12 + i9
return 0;
}
Viva Questions
1. What is the difference between protected and private members in a class?
2. Can protected members be accessed outside the class hierarchy?
3. How does public inheritance differ from protected and private inheritance in C++?
4. What happens to the private members of a base class when inherited?
5. Why is operator overloading necessary in C++?
6. Can all operators be overloaded in C++? Give an example of an operator that cannot be
overloaded.
7. What is the syntax for overloading the + operator in a class?
8. Why should the operator overloading function be defined as a member function or a
friend function?
9.
Theory Questions
1. Explain the significance of protected members in the context of inheritance.
2. Write a C++ program to demonstrate the use of protected members in a base and derived
class.
3. Explain the concept of protected inheritance with an example.
4. Describe the accessibility of base class members in private inheritance.
5. Explain with an example how operator overloading enhances code readability.
6. Discuss the advantages and disadvantages of operator overloading.
7. Write the syntax for overloading the << operator for a class and explain each part.
8. Explain the difference between member and non-member operator overloading functions
with examples.
Session :5
Overloading an Operator: Some Restrictions, The Pointer this, Friend Functions of Classes, Operator Functions as Member Functions and Non-member Functions,
Overloading Binary Operators, Overloading the Stream Insertion (<<) and Extraction (>>) Operators,
void print() {
cout << real << " + i" << imag << endl;
}
};
int main() {
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2; // Using overloaded +
c3.print(); // Output: 12 + i9
return 0;
}
void print() {
cout << "x = " << x << endl;
}
};
int main() {
Test obj;
obj.setX(20);
obj.print(); // Output: x = 20
return 0;
}
private:
int meter;
public:
Distance() : meter(0) {}
// Friend function declaration
friend int addFive(Distance);
};
void print() {
cout << real << " + i" << imag << endl;
}
};
int main() {
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2; // Using overloaded + (member function)
c3.print(); // Output: 12 + i9
return 0;
}
5. Overloading Binary Operators
Key Points:
❖ Definition: Binary operators take two operands. Can be overloaded as member or non-member functions.
❖ Syntax: Member function: Return Type operator op (const Type& operand); Non-member function: Return
Type operator op (const Type& lhs, const Type& rhs);
Example:
class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i = 0) : real(r), imag(i) {}
// Overloading the + operator
Complex operator+(const Complex& obj) {
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() {
cout << real << " + i" << imag << endl;
}
};
int main() {
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2; // Using overloaded +
c3.print(); // Output: 12 + i9
return 0;
}
#include <iostream>
using namespace std;
class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i = 0) : real(r), imag(i) {}
// Member function for overloading +
Complex operator+(const Complex& obj) {
return Complex(real + obj.real, imag + obj.imag);
}
// Friend function for overloading <<
friend ostream& operator<<(ostream& out, const Complex& c) {
out << c.real << " + i" << c.imag;
return out;
}
};
int main() {
Complex c1(3, 4), c2(1, 2);
Complex c3 = c1 + c2;
cout << "Sum: " << c3 << endl;
return 0;
}
3. Function Overloading
Function overloading allows multiple functions with the same name to exist, provided they
have different parameter lists. It is a form of compile-time polymorphism.
Key Points
❖ Functions must differ in the number or type of their parameters.
❖ Return type alone is not sufficient to distinguish overloaded functions.
❖ Improves code readability and reusability.
Example:
#include <iostream>
using namespace std;
// Function to add two integers
int add(int a, int b) {
return a + b;
}
// Function to add two doubles
double add(double a, double b) {
return a + b;
}
int main() {
cout << "Sum of integers: " << add(3, 4) << endl;
cout << "Sum of doubles: " << add(3.5, 4.5) << endl;
return 0;
}
#include "Array.cpp"
#endif
Implementation File (Array.cpp)
#include "Array.h"
#include <iostream>
using namespace std;
Theory Questions
1. Describe the advantages and disadvantages of using friend functions for operator overloading.
2. Write a C++ program to overload the * operator for a class representing complex numbers.
3. Write a C++ program to overload the - operator for a class representing complex numbers.
4. Discuss the importance of overloading the stream insertion and extraction operators for complex numbers.
5. Write a C++ program to overload the max function for different data types.
6. Explain the rules and restrictions for function overloading in C++.
7. Write a function template to find the maximum of two values.
8. Discuss the advantages and disadvantages of using function templates.
9. Write a class template for a stack data structure.
10. Discuss the benefits of using class templates in C++.
11. Write a header file and an implementation file for a class template representing a dynamic array.
12. Discuss the advantages and disadvantages of separating template class definitions and implementations.
Session :7
give me a detailed notes on each of the following topics in c++ with explanation, key points and a simple example :
give me 2 viva questions and 2 theory questions for exam on each of the following topics answers not required only the questions:
Pointer Data Type and Pointer Variables: Declaring Pointer Variables, Address of Operator (&), Dereferencing Operator (*), Pointers and Classes, Initializing Pointer
Variables, Dynamic Variables, Operator new, Operator delete, Operations on Pointer Variables, Dynamic Arrays, Array
MyClass obj;
MyClass *ptr = &obj;
ptr->data = 5;
6. Dynamic Variables
Explanation: Dynamic variables are allocated memory at runtime using the new operator.
Key Point:
❖ Use new to allocate memory and delete to deallocate.
Example:
int *ptr = new int;
*ptr = 10;
delete ptr;
7. Operator new
Explanation: The new operator allocates memory for a variable at runtime.
Key Point:
❖ Returns a pointer to the allocated memory.
Example:
int *ptr = new int;
8. Operator delete
The delete operator deallocates memory that was previously allocated with new.
Key Point:
❖ Prevents memory leaks.
Example:
delete ptr;
Viva Questions
What is a pointer and how is it declared in C++?
Explain the difference between the address-of operator (&) and the dereferencing operator
Theory Questions
Describe the process of dynamic memory allocation in C++ using the new and delete
operators.
How can pointers be used to access members of a class in C++?
Feel free to ask if you need further details or examples on any specific topic!
Session :8
give me a detailed notes on each of the following topics in c++ with explanation, key points and a simple example :
give me 2 viva questions and 2 theory questions for exam on each of the following topics answers not required only the questions:
Name: A Constant Pointer, Functions and Pointers, Pointers and Function Return Values, Dynamic Two-Dimensional Arrays,
1. Constant Pointer
A constant pointer is a pointer whose address cannot be changed after initialization.
However, the value at the address it points to can be modified.
Key Points:
❖ Declared using the const keyword.
❖ Must be initialized at the time of declaration.
❖ The pointer itself cannot point to another address after initialization.
Example:
#include <iostream>
using namespace std;
int main() {
int a = 10;
int b = 20;
int* const ptr = &a; // Constant pointer to 'a'
int main() {
int num = 10;
increment(&num);
cout << "Value of num: " << num << endl; // Output: 11
return 0;
}
int main() {
int* myArray = createArray(5);
for (int i = 0; i < 5; i++) {
cout << myArray[i] << " "; // Output: 1 2 3 4 5
}
delete[] myArray; // Free the allocated memory
return 0;
}
// Deallocate memory
for (int i = 0; i < rows; i++) {
delete[] arr[i];
}
delete[] arr;
return 0;
}
Viva Questions:
What is a constant pointer in C++?
Can the address stored in a constant pointer be changed after initialization?
How do you pass a pointer to a function in C++?
What are the advantages of using pointers in function arguments?
Can a function return a pointer in C++?
What precautions should be taken when returning pointers from functions?
How do you create a dynamic two-dimensional array in C++?
What are the advantages of using dynamic arrays over static arrays?
Theory Questions:
Explain the difference between a constant pointer and a pointer to a constant.
Write a C++ program to demonstrate the use of a constant pointer.
Write a function that swaps two integers using pointers.
Explain how pointers can be used to return multiple values from a function.
Write a function that returns a pointer to a dynamically allocated array.
Explain the concept of memory leaks and how to prevent them when using pointers.
Write a C++ program to create and initialize a dynamic two-dimensional array.
Explain the process of deallocating memory for a dynamic two-dimensional array.
Session :9
give me a detailed notes on each of the following topics in c++ with explanation, key points and a simple example :
give me 2 viva questions and 2 theory questions for exam on each of the following topics answers not required only the questions:
Shallow Vs. Deep Copy and Pointers, Destructor, Classes &Pointers Assignment Operator, Copy Constructor,
1. Shallow vs. Deep Copy and Pointers
• Shallow Copy: Copies all member values from one object to another. If the object contains
pointers, only the pointer addresses are copied, not the actual data they point to.
• Deep Copy: Copies all member values and the data pointed to by any pointers. This ensures
that the new object is completely independent of the original.
Key Points:
❖ Shallow copy can lead to issues like dangling pointers and double deletion.
❖ Deep copy requires a user-defined copy constructor and assignment operator.
Example:
#include <iostream>
using namespace std;
class Box {
private:
int* ptr;
public:
Box(int val) {
ptr = new int;
*ptr = val;
}
// Copy Constructor for Deep Copy
Box(const Box& b) {
ptr = new int;
*ptr = *(b.ptr);
}
void setValue(int val) {
*ptr = val;
}
void display() {
cout << "Value: " << *ptr << endl;
}
~Box() {
delete ptr;
}
};
int main() {
Box box1(10);
Box box2 = box1; // Deep copy
box2.setValue(20);
box1.display(); // Output: Value: 10
box2.display(); // Output: Value: 20
return 0;
}
2. Destructor
A destructor is a special member function that is executed when an object goes out of scope
or is explicitly deleted. It is used to release resources allocated to the object.
Key Points:
❖ Declared with a tilde (~) followed by the class name.
❖ No return type and no parameters.
❖ Automatically called when an object is destroyed.
Example:
#include <iostream>
using namespace std;
class Demo {
public:
Demo() {
cout << "Constructor called" << endl;
}
~Demo() {
cout << "Destructor called" << endl;
}
};
int main() {
Demo obj;
return 0;
}
class Box {
private:
int* ptr;
public:
Box(int val) {
ptr = new int;
*ptr = val;
}
// Assignment Operator for Deep Copy
Box& operator=(const Box& b) {
if (this != &b) {
delete ptr;
ptr = new int;
*ptr = *(b.ptr);
}
return *this;
}
void display() {
cout << "Value: " << *ptr << endl;
}
~Box() {
delete ptr;
}
};
int main() {
Box box1(10);
Box box2(20);
box2 = box1; // Deep copy
box1.display(); // Output: Value: 10
box2.display(); // Output: Value: 10
return 0;
}
4. Copy Constructor
A copy constructor is a special constructor used to create a new object as a copy of an
existing object. It is essential for deep copying.
Key Points:
❖ Takes a reference to an object of the same class as a parameter.
❖ Used to initialize an object from another object.
Example:
#include <iostream>
using namespace std;
class Box {
private:
int* ptr;
public:
Box(int val) {
ptr = new int;
*ptr = val;
}
// Copy Constructor for Deep Copy
Box(const Box& b) {
ptr = new int;
*ptr = *(b.ptr);
}
void display() {
cout << "Value: " << *ptr << endl;
}
~Box() {
delete ptr;
}
};
int main() {
Box box1(10);
Box box2 = box1; // Deep copy using copy constructor
box1.display(); // Output: Value: 10
box2.display(); // Output: Value: 10
return 0;
}
Viva Questions:
1. What is the difference between shallow copy and deep copy?
2. Why is a deep copy necessary when dealing with pointers?
3. What is the purpose of the assignment operator in C++?
4. How can you ensure a deep copy using the assignment operator?
5. What is a destructor in C++?
6. When is a destructor called
7. What is a copy constructor in C++?
8. When is a copy constructor called?
Theory Questions:
1. Explain the potential issues with shallow copying in C++.
2. Write a C++ program to demonstrate deep copying.
3. Explain the difference between the default and custom assignment operators.
4. Write a C++ program to demonstrate the use of a custom assignment operator.
5. Explain the role of a destructor in resource management.
6. Write a C++ program to demonstrate the use of a destructor.
7. Explain the importance of a copy constructor in C++.
8. Write a C++ program to demonstrate the use of a copy constructor.
Session :10
give me a detailed notes on each of the following topics in c++ with explanation, key points and a simple example :
give me 2 viva questions and 2 theory questions for exam on each of the following topics answers not required only the questions:
Inheritance Pointers &Virtual functions: Classes and Virtual Destructors 168, Array Based Lists:
Copy Constructor, Overloading the Assignment Operator, Search, Insert, Remove, Time Complexity of List Operations
class Base {
public:
Base() { cout << "Base Constructor\n"; }
virtual ~Base() { cout << "Base Destructor\n"; }
virtual void show() { cout << "Base show\n"; }
};
int main() {
Base* b = new Derived();
b->show();
delete b;
return 0;
}
When Base* b = new Derived(); is executed, the Base class constructor is called first,
printing “Base Constructor”. Next, the Derived class constructor is called, printing “Derived
Constructor”. The show function is called on the Base pointer b. Since show is a virtual
function, the Derived class’s show method is called, printing “Derived show”. When delete b;
is executed, the Derived class destructor is called first, printing “Derived Destructor”,
followed by the Base class destructor, printing “Base Destructor”.
2. Array-Based Lists
Array-based lists use arrays to store elements. They provide efficient access and
modification but have fixed size, requiring resizing for dynamic operations.
Key Points
❖ Copy Constructor: Creates a new object as a copy of an existing object.
❖ Overloading the Assignment Operator: Allows assigning one object to another.
❖ Search: Finding an element in the list.
❖ Insert: Adding an element to the list.
❖ Remove: Deleting an element from the list.
❖ Time Complexity: Efficiency of list operations.
Example
#include <iostream>
using namespace std;
class ArrayList {
private:
int* arr;
int size;
int capacity;
public:
ArrayList(int cap) : size(0), capacity(cap) {
arr = new int[capacity];
}
~ArrayList() {
delete[] arr;
}
void display() {
for (int i = 0; i < size; ++i) {
cout << arr[i] << " ";
}
cout << endl;
}
};
int main() {
ArrayList list(10);
list.insert(5);
list.insert(10);
list.insert(15);
list.display();
list.remove(1);
list.display();
cout << "Index of 15: " << list.search(15) << endl;
return 0;
}
In the above code The insert method adds elements to the list. If the list is not full, the
element is added, and the size is incremented. The remove method deletes an element at a
specified index. It shifts all subsequent elements one position to the left and decrements the
size. The search method looks for an element in the list. It returns the index of the element if
found, otherwise returns -1 and the display method prints all elements in the list.
Viva Questions
What is the purpose of a virtual destructor in C++?
How does polymorphism work in C++?
What is the difference between a copy constructor and an assignment operator?
How do you handle dynamic resizing in an array-based list?
Theory Questions
Explain the concept of inheritance and its types in C++.
Describe the role of virtual functions in achieving runtime polymorphism.
Explain the time complexity of search, insert, and remove operations in an array-based list.
Describe the process of overloading the assignment operator in C++.