C++ Module 2
C++ Module 2
By
Mysore University School of Engineering
University of Mysore
Mysuru
1 P.T.O
C++ | 2
MODULE 2
The members that have been declared as private can be accessed only from within the class. On the other hand, public
members can be accessed from outside the class also.
The data hiding is the key feature of oops.
• The use of keywords private is optional by default, the members of a class are private.
• The variables declared inside the class are known as data members and the functions are known as members
mid the functions.
• Only the member functions can have access to the private data members and private functions.
• The public members can be accessed from the outside the class.
• The binding of data and functions together into a single class type variable is referred to as encapsulation.
Syntax: -
class item
{
int member;
float cost;
public: void getdata (int a, float b);
void putdata (void);
The class item contains two data members and two function members, the data members are private by default while
both the functions are public by declaration. The function getdata() can be used to assign values to the member variables
member and cost, and putdata() for displaying their values. These functions provide the only access to the data members
from outside the class.
CREATING OBJECTS: Once a class has been declared we can create variables of that type by using the class name.
Example:
item x;
creates a variables x of type item. In C++, the class variables are known as objects. Therefore, x is called an object of
type item. item x, y, z also possible.
class item
{
----------------
----------------
}
x, y, z;
would create the objects x, y, z of type item.
x. number = 100 is illegal. Although x is an object of the type item to which number belongs, the number can be
accessed only through a member function and not by the object directly.
Example:
class xyz
{
int x;
int y;
public: int z;
};
---------
----------
xyz p;
The member function definitions are placed outside the class, below the class definition, and preceded by the class
name followed by the scope resolution operator ::. These definitions specify the return type and the name of the class
to which the function belongs.
• Defining member functions outside the class provides a way to separate the declaration (in the class) from the
implementation (outside the class).
C++ | 4
• It helps in keeping the class definition clean and concise, especially when dealing with complex functions.
By using outside the class definitions, you can group related functions together, enhance code readability, and promote
modularity in your C++ programs.
Member function that are declared inside a class have to be defined separately outside the class. Their definition is very
much like the normal functions. An important difference between a member function and a normal function is that a
member function incorporates a membership. Identify label in the header. The ‘label’ tells the compiler which class the
function belongs to.
Syntax:
type class-name::function-name(argument declaration )
{
function-body
}
• The membership label class-name:: tells the compiler that the function function - name belongs to the class
class-name.
• That is the scope of the function is restricted to the class name specified in the header line.
• The :: symbol is called scope resolution operator.
Example:
void item :: getdata (int a, float b )
{
number=a;
cost=b;
}
void item :: putdata ( void)
{
cout<<”number=:”<<number<<endl;
cout<<”cost=”<<cost<<endl;
}
1. The member function has some special characteristics that are often used in the program development.
2. Several different classes can use the same function name. The "membership label" will resolve their scope,
member functions can access the private data of the class.
3. A non-member function can't do so.
4. A member function can call another member function directly, without using the dot operator.
In C++, when a member function is defined inside the class definition itself, it is known as an "inside the class
definition" or "inline definition". This means that the member function's definition is directly included within the class
declaration, typically within the public or private section.
Example:
#include <iostream>
using namespace std;
// Class declaration
class MyClass {
private:
int myVar;
public:
// Method to set the value of myVar
void setMyVar(int value) {
myVar = value;
}
// Method to display the value of myVar
void displayMyVar() {
cout << "myVar: " << myVar << endl;
}
};
int main() {
MyClass obj;
obj.setMyVar(42);
C++ | 5
obj.displayMyVar();
return 0;
}
Another method of defining a member function is to replace the function declaration by the actual function definition
inside the class.
• The member function definitions are directly included inside the class definition. This means that the functions'
implementations are provided immediately following their declarations, without the need for separate
definitions outside the class.
• Defining member functions inside the class provides a compact and concise way to specify the behaviour of the
class.
• It allows you to define and implement small, straightforward functions directly within the class declaration
itself.
• Using inside the class definitions is suitable for simple member functions that do not require extensive
implementation or for functions that are tightly coupled with the class's internal state and data members.
Example:
class item
{
int number;
float cost;
public:
void getdata(int a, float b);
void putdata(void)
{
cout<<number<<endl;
cout<<cost<<endl;
}
};
Example:
#include <iostream>
using namespace std;
// Define a class
class MyClass {
private:
// Member variables (data)
int myVar1;
float myVar2;
public:
// Constructor
MyClass(int intVal, float floatVal) {
myVar1 = intVal;
myVar2 = floatVal;
}
// Accessor functions (getters)
int getMyVar1() {
return myVar1;
}
float getMyVar2() {
return myVar2;
}
// Mutator functions (setters)
void setMyVar1(int value) {
myVar1 = value;
}
void setMyVar2(float value) {
myVar2 = value;
C++ | 6
}
// Display function
void display() {
cout << "myVar1: " << myVar1 << ", myVar2: " << myVar2 << endl;
}
};
int main() {
// Create objects of the class
MyClass obj(10, 20.5);
// Access and modify member variables using accessor and mutator functions
obj.setMyVar1(42);
obj.setMyVar2(55.5);
// Call member functions
obj.display();
return 0;
}
Note (Imp***): Write a simple program using class in C++ to input subject mark and prints it.
#include <iostream>
using namespace std;
class Marks {
private:
int m1, m2;
public:
// Function to get data from user
void getData() {
cout << "Enter 1st subject mark: ";
cin >> m1;
cout << "Enter 2nd subject mark: ";
cin >> m2;
}
// Function to display data
void displayData() {
cout << "1st subject mark: " << m1 << endl;
cout << "2nd subject mark: " << m2 << endl;
}
};
int main() {
Marks x;
x.getData();
x.displayData();
return 0;
}
NESTING OF MEMBER FUNCTION: Nesting of member functions in C++ refers to the ability to define a member
function inside another member function of the same class. This allows the nested function to access the enclosing
function's variables and members directly.
A member function can be called by using its name inside another member function of the same class. This is known as
nesting of member functions.
Example:
#include <iostream>
using namespace std;
// Class declaration
class MyClass {
private:
int myVar;
// Helper function (acts like a nested function)
void innerFunction() {
cout << "Inner function called" << endl;
cout << "myVar: " << myVar << endl; // Accessing member variable
}
public:
C++ | 7
void outerFunction() {
myVar = 10; // Accessing member variable directly
innerFunction(); // Calling the inner helper function
}
};
int main() {
MyClass obj;
obj.outerFunction(); // Calling the outer function
return 0;
}
The nested function ‘innerFunction()’ can access the member variable myVar directly from the outer function.
• It has access to all the variables and members of the enclosing function, including the member variables of the
class. Nesting member functions can be useful in situations where a particular function requires the use of
auxiliary functions or when you want to encapsulate specific functionality within a member function.
• It's important to note that the nested function can only be called from within the outer function.
• It is not directly accessible outside of the enclosing function.
• Nesting member functions can help organize and structure code, making it more readable and maintainable by
keeping related functions together within a class.
• However, it is recommended to use nesting sparingly and only when it provides clear benefits in terms of code
organization and readability.
However, attempting to call the private function directly from outside the class, like obj.privateFunction(), would result
in a compilation error. Private member functions help enforce encapsulation and hide internal implementation details of
a class from external code. They allow you to structure your class's functionality and divide it into smaller, more
manageable pieces, improving code organization and maintainability.
This allows you to perform operations on a collection of objects in a systematic and efficient manner.
ARRAY OF OBJECTS:-
An array of objects in C++ refers to a data structure that allows you to store multiple instances of a class in a contiguous
memory block. It provides a convenient way to work with collections of objects, accessing and manipulating them using
array indexing.
Example:
#include <iostream>
using namespace std;
// Class declaration
class MyClass {
private:
int value;
public:
void setValue(int v) {
value = v;
}
void displayValue() {
cout << "Value: " << value << endl;
}
};
int main() {
const int SIZE = 5;
MyClass objArray[SIZE]; // Array of MyClass objects
// Assign values to array elements
for (int i = 0; i < SIZE; i++) {
objArray[i].setValue(i * 10);
}
// Display values of array elements
for (int i = 0; i < SIZE; i++) {
objArray[i].displayValue();
}
return 0;
}
In this example,
• A class called MyClass with a private member variable value.
• The class includes two member functions: setValue() to set the value of value, and displayValue() to display
the value.
• Inside the main() function, declare an array objArray of MyClass objects with a size of 5.
• Each element of the array is an object of the MyClass class.
C++ | 11
• Use a loop to assign values to each element of the array using the setValue() function.
• In this case, we assign values that are multiples of 10 based on the array index. Finally, use another loop to
display the values of each element in the array using the displayValue() function.
• Arrays of objects allow you to store and manipulate multiple instances of a class in a structured manner.
Access individual objects in the array using array indexing and perform operations on them using member function calls.
This provides a convenient way to work with collections of objects and perform operations on them collectively.
To illustrate replacing and sorting elements using a class, let's consider an example of a class representing a collection of
integers. We'll define methods to replace an element and sort the elements in ascending order.
Example:
#include <iostream>
#include <algorithm>
using namespace std;
// Class declaration
class IntegerCollection {
private:
int* elements;
int size;
public:
// Constructor to initialize the collection with an array
IntegerCollection(int arr[], int n) {
size = n;
elements = new int[size];
for (int i = 0; i < size; i++) {
elements[i] = arr[i];
}
}
// Function to replace an element at a given index
void replaceElement(int index, int newValue) {
if (index >= 0 && index < size) {
elements[index] = newValue;
cout << "Element replaced successfully." << endl;
} else {
cout << "Invalid index. Replacement failed." << endl;
}
}
// Function to sort the elements in ascending order
void sortElements() {
sort(elements, elements + size);
cout << "Elements sorted in ascending order." << endl;
}
// Function to display the elements
void displayElements() {
for (int i = 0; i < size; i++) {
cout << elements[i] << " ";
}
cout << endl;
}
// Destructor to deallocate dynamically allocated memory
~IntegerCollection() {
delete[] elements;
}
};
int main() {
int arr[] = { 5, 2, 7, 3, 1 };
int size = sizeof(arr) / sizeof(arr[0]);
// Create an IntegerCollection object
IntegerCollection collection(arr, size);
// Display the original elements
cout << "Original elements: ";
C++ | 12
collection.displayElements();
// Replace an element at index 2 with 10
collection.replaceElement(2, 10);
cout << "Elements after replacement: ";
collection.displayElements();
// Sort the elements
collection.sortElements();
cout << "Elements after sorting: ";
collection.displayElements();
return 0;
}
In this example, define the IntegerCollection class that represents a collection of integers.
• The class has a private member variable element which is a dynamically allocated array to store the integers,
and a size variable to keep track of the array size.
• The class constructor takes an array and its size as parameters and initializes the elements array with the
provided values.
• The replaceElement() method allows replacing an element at a specific index with a new value. It checks if the
index is valid and updates the element accordingly.
• The sortElements() method utilizes the std::sort() algorithm from the <algorithm> library to sort the elements
in ascending order. The displayElements() method is used to display the elements of the collection. In the
main() function,
• Create an instance of the IntegerCollection class, passing an array of integers and its size.
• Demonstrate the usage of the replaceElement() method by replacing an element at a specific index, and the
sortElements() method to sort the elements.
• Display the elements before and after the operations.
ARRAY OF MEMBERS:
In C++, an array of members refers to an array that stores multiple objects of a class, where each object represents a
member of a group or a collection. Each element of the array corresponds to a specific member of the group.
Example:
#include <iostream>
using namespace std;
// Class declaration
class Member {
private:
string name;
int age;
public:
Member(string n, int a) {
name = n;
age = a;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
const int SIZE = 3;
Member members[SIZE] = {
Member("John", 25),
Member("Alice", 30),
Member("Bob", 35)
};
for (int i = 0; i < SIZE; i++) {
members[i].display();
}
return 0;
}
In this example,
C++ | 13
• Have a class called Member, representing a member of a group.
• The class has private member variables name and age, as well as a constructor to initialize these variables.
• Additionally, it includes a member function called display() to display the member's name and age. Inside the
main() function, create an array members of Member objects with a size of 3.
• Each element of the array represents a member, and we initialize them using the constructor with different
names and ages.
• Use a loop to iterate over each element of the array and call the display() member function to display the details
of each member. Arrays of members allow you to store and manage multiple objects of a class,
• where each object represents a distinct member of a group or collection.
• This can be useful in scenarios such as managing a list of employees, students, or any other group of
individuals, where each object represents a member with specific attributes or data.
The static Variable count is initialized to Zero when the objects created. The count is incremented whenever the data is
read into an object. Since the data is read into objects three times the variable count is incremented three times. Because
there is only one copy of count shared by all the three objects, all the three output statements cause the value 3 to be
displayed.
Example 2:
#include <iostream>
using namespace std;
// Class declaration
class MyClass {
private:
int myVar;
static int count; // Declaration of static data member
public:
MyClass() {
myVar = 0;
count++; // Incrementing the static data member in the constructor
}
void setMyVar(int value) {
myVar = value;
}
void display() const {
cout << "myVar: " << myVar << endl;
}
static void displayCount() {
cout << "Count: " << count << endl;
}
};
int MyClass::count = 0; // Initialization of static data member
int main() {
MyClass obj1;
obj1.setMyVar(10);
MyClass obj2;
obj2.setMyVar(20);
obj1.display();
obj2.display();
MyClass::displayCount();
return 0;
}
• The member functions setMyVar() and display() operate on the non-static member variable myVar and
display its value.
• The static member function displayCount() is associated with the class itself rather than individual objects.
• It can directly access the static data member count to display the total count of objects created.
• In the main() function, we create two objects obj1 and obj2 of the MyClass class.
• Set different values for the myVar member variable of each object using the setMyVar() function. Then, we
display the values using the display() function.
• Finally, call the static member function displayCount() using the class name MyClass to display the total count
of objects created.
• Static data members are useful when you need to maintain data that is shared among all objects of a class and
doesn't need to be duplicated for each object.
• They provide a way to keep track of common data or maintain global state within the scope of the class.
C++ | 15
STATIC MEMBER FUNCTIONS:-
A static member function is a function that belongs to a class rather than an instance of the class. It is associated with the
class itself and not with any specific object or instance of the class.
key characteristics and properties of static member functions:
• Belongs to the class: A static member function is declared and defined within a class, just like regular member
functions. However, it is not tied to any specific object or instance of the class.
• Independent of object state: Since static member functions do not have access to the specific object's data
members or member variables, they are not allowed to access non-static member variables directly. Static
member functions can only access other static members (variables or functions) of the class.
• Invoked using the class name: Unlike regular member functions, which are called using an instance of the
class, static member functions are invoked using the class name followed by the scope resolution operator (::).
For example, if a class named "MyClass" has a static member function called "staticFunction," it can be called
as "MyClass::staticFunction()".
• No "this" pointer: Since static member functions do not operate on a specific object, they do not have a "this"
pointer. The "this" pointer is a pointer to the current object being operated on by a member function.
• Can be accessed without an instance: Static member functions can be accessed directly using the class name,
without the need to create an instance of the class. This makes them useful for utility functions or operations
that do not require object-specific data.
• Shared among all class instances: Static member functions are shared among all instances of a class. Any
modifications made to a static member variable inside a static member function will affect all objects of that
class.
• Global accessibility: Static member functions are globally accessible, meaning they can be called from
anywhere in the program as long as the class is visible in the current scope.
Static member functions are commonly used for tasks that are related to the class as a whole, such as utility functions,
helper functions, or operations that do not depend on specific object instances.
A member function that is declared static has following properties :-
1. A static function can have access to only other static members declared in the same class.
2. A static member function can be called using the class name as follows:- class - name :: function - name;
Example:-
#include <iostream>
using namespace std;
class Test {
int code;
static int count; // Static member variable
public:
void setCode() {
code = ++count;
}
void showCode() const {
cout << "Object member: " << code << endl;
}
static void showCount() {
cout << "Count = " << count << endl;
}
};
int Test::count = 0; // Initialize static member variable
int main() {
Test t1, t2;
t1.setCode();
t2.setCode();
Test::showCount(); // Show count after creating two objects
Test t3;
t3.setCode();
Test::showCount(); // Show count after creating the third object
t1.showCode();
t2.showCode();
t3.showCode();
return 0;
}
C++ | 16
output:-
count : 2
count: 3
object number 1
object number 2
object number 3
Objects as function arguments refer to passing instances of a class or objects of a specific type as parameters to a
function. This allows the function to operate on or utilize the data and behavior of the passed object.Like any other data
type, an object may be used as A function argument.
A friendly function, also known as a friend function, is a function that is granted access to the private and
protected members of a class, even though it is not a member of that class.
In other words, a friendly function is an external function that can access the private and protected members of a
class as if it were a member function.
• Not a member of the class: Unlike regular member functions, a friendly function is not a member of the class
in which it is declared. It is defined outside the class but has the ability to access the private and protected
members of the class.
• Granted access to private and protected members: By declaring a function as a friend of a class, that
function is given access to the private and protected members of the class. This allows the friendly function to
manipulate and view the internal state of the class, even though it is not part of the class itself.
• Declaration inside the class: The declaration of a friendly function is typically included within the class
definition, preceded by the "friend" keyword. This informs the compiler that the function is a friend of the class
and should be granted access to its private and protected members.
• Global or external function: Friendly functions are defined outside the class, usually in the same file or a
separate file. They can be standalone functions or part of another unrelated class.
• Used for specific operations: Friendly functions are often employed when certain operations need to access
the private or protected members of a class but do not necessarily fit as regular member functions. They can
provide additional functionality or facilitate operations involving multiple objects or classes.
• No implicit object parameter: Unlike member functions, friendly functions do not have an implicit object
parameter ("this" pointer) since they are not associated with any specific object of the class. They operate on
the class's private and protected members directly, without any object context.
• Friendship is not transitive: The friendship relationship is not transitive. Being a friend of a class does not
automatically make a function a friend of another class. Friendship must be explicitly granted by each class
individually.
Friendly functions can be useful for accessing or manipulating the private and protected members of a class when it
is necessary to perform specific operations that do not fit well within the context of regular member functions.
However, the usage of friendly functions should be approached with caution, as they can potentially undermine
encapsulation and increase coupling between classes.
• We know private members cannot be accessed from outside the class. That is a non - member function can't
have an access to the private data of a class.
• However, there could be a case where two classes manager and scientist, have been defined we should like to
use a function income tax to operate on the objects of both these classes.
• In such situations, c++ allows the common function lo be made friendly with both the classes, there by
following the function to have access to the private data of these classes.
• Such a function need not be a member of any of these classes. To make an outside function "friendly" to a
class,
Declare this function as a friend of the classes as shown below:
class ABC
{
---------
---------
public:
--------
----------
friend void xyz(void);
};
• The function declaration should be preceded by the keyword friend, The function is defined elsewhere in the
program like a normal C ++ function.
• The function definition does not use their the keyword friend or the scope operator ::.
• The functions that are declared with the keyword friend are known as friend functions.
• A function can be declared as a friend in any no of classes.
• A friend function, as though not a member function, has full access rights to the private members of the class.
C++ | 18
A friend function processes certain special characteristics:
1. It is not in the scope of the class to which it has been declared as friend.
2. Since it is not in the scope of the class, it cannot be called using the object of that class. It can be invoked like a
member function without the help of any object.
3. Unlike member functions.
Example:
#include <iostream>
using namespace std;
class Sample {
int a;
int b;
public:
void setValue() {
a = 25;
b = 40;
}
friend float mean(Sample s);
};
float mean(Sample s) {
return (float(s.a + s.b) / 2.0);
}
int main() {
Sample x;
x.setValue();
cout << "Mean value = " << mean(x) << endl;
return 0;
}
In real-world scenarios, the private data members of a class could be more complex, such as objects, arrays, or other
data structures. The swapping operation would need to consider the appropriate logic based on the specific data types.
Swapping private data of classes can be useful when you need to interchange or modify the internal state of two objects
while maintaining encapsulation and access control through appropriate friend functions.
Note: Imp****
PROGRAM FOR ILLUSTRATING THE USE OF FRIEND FUNCTION:
#include <iostream>
class MyClass {
private:
int privateData;
public:
// Constructor to initialize privateData
MyClass(int data) : privateData(data) {}
// Friend function declaration
friend void printPrivateData(const MyClass& obj);
};
// Definition of the friend function
void printPrivateData(const MyClass& obj) {
std::cout << "Private data: " << obj.privateData << std::endl;
}
int main() {
MyClass obj(42);
printPrivateData(obj);
return 0;
}
C++ | 20
RETURNING OBJECTS:
• Returning objects from functions allows you to return instances of classes as the result of a function call.
• This feature is supported by the language and is commonly used to return complex data structures or
encapsulated functionality.
Example:
MyClass getMyClassObject()
{
// ...
return MyClass(); // Return an instance of MyClass
}
class MyClass {
public:
MyClass(int value) : data(value) {}
int getData() const { return data; }
private:
int data;
};
MyClass createMyClassObject(int value) {
return MyClass(value); // Return an instance of MyClass
}
int main() {
MyClass obj = createMyClassObject(42); // Returned object assigned to obj
int data = obj.getData(); // Accessing data member of returned object
return 0;
}
POINTER To MEMBERS:
• A pointer to a member in C++ is a special type of pointer that can store the address of a member variable or a
member function of a class.
• Pointers to members allow you to access or manipulate members of a class through the pointer, enabling
dynamic and flexible behavior at runtime.
Syntax: The syntax for declaring a pointer to a member depends on whether it is a pointer to a member variable or a
pointer to a member function.
• Pointer to a member variable: int MyClass::*ptrToMember; // Pointer to a member variable of type int
in MyClass
C++ | 21
• Member variable pointer: A pointer to a member variable stores the offset from the beginning of the class
object to the specific member variable. It does not store the value of the member variable itself. It allows you to
access or modify the member variable through the pointer using the object's address.
• Member function pointer: A pointer to a member function stores the address of the member function within
the class. It can be used to invoke the member function on a specific object of the class or through an object
pointer. Member function pointers also preserve information about the class type and function signature.
• Accessing member variable through pointer: To access a member variable through a pointer to a member,
you need an object of the corresponding class. You can use the pointer-to-member syntax along with the
object's address and the .* or ->* operators. For example:
MyClass obj;
int value = obj.*ptrToMember; // Access member variable using object and pointer-to-member
• Invoking member function through pointer: To invoke a member function through a pointer to a member,
you need an object of the corresponding class or a pointer to that object. You can use the pointer-to-member-
function syntax along with the object or pointer and the .* or ->* operators. For example:
MyClass obj;
(obj.*ptrToMemberFn)(); // Invoke member function using object and pointer-to-member-function
• Polymorphism and pointers to members: Pointers to members can be used with polymorphic classes. When
dealing with a base class and derived classes, the correct member variable or function is resolved at runtime
based on the dynamic type of the object or pointer.
• Restrictions: Pointers to members have certain limitations, such as they cannot be used to access static
members, non-public members (unless they are accessible due to friend relationship), or virtual members
directly.
Pointers to members provide a powerful mechanism for dynamic dispatch and manipulation of class members at runtime.
They allow for flexible and runtime-specific behavior in situations where the specific member to access or function to
call needs to be determined dynamically.
DEREFERENCING OPERATOR:
• The dereferencing operator in C++ is used to access the value pointed to by a pointer.
• It is represented by the asterisk (*) symbol.
• When applied to a pointer, the dereferencing operator retrieves the value stored at the memory address pointed
to by the pointer.
Syntax: The dereferencing operator is placed before a pointer variable or expression, using the asterisk (*) symbol.
For example:
int *ptr; // Declaration of a pointer variable
int value = *ptr; // Dereferencing the pointer to retrieve the value
• Dereferencing a pointer: When the dereferencing operator is applied to a pointer, it returns the value stored at
the memory location pointed to by the pointer. This allows you to access or modify the value indirectly through
the pointer. For example:
int *ptr = new int; // Creating a dynamic memory allocation
*ptr = 42; // Assigning a value to the memory location pointed to by ptr
int value = *ptr; // Dereferencing ptr to retrieve the value
• Accessing members of a pointer to an object: If a pointer points to an object, the dereferencing operator can
be used to access the members of the object. This is done by combining the dereferencing operator with the
member access operator (->) for pointers to objects.
C++ | 22
For example:
struct MyClass {
int data;
};
MyClass *ptr = new MyClass;
ptr->data = 42; // Accessing the data member of the object pointed to by ptr
• Null pointer dereferences: Dereferencing a null pointer, i.e., a pointer that does not point to a valid memory
address, results in undefined behavior. It is crucial to ensure that a pointer is properly initialized and points to
valid memory before dereferencing it.
The dereferencing operator allows you to retrieve the value or access the members of an object pointed to by a pointer. It
is an essential operator when working with pointers and enables indirect access to data and functionality in C++.
Example:
#include <iostream>
using namespace std;
class M {
int x;
int y;
public:
void set_xy(int a, int b) {
x = a;
y = b;
}
friend int sum(M);
};
int sum(M m) {
int M::*px = &M::x; // pointer to member x
int M::*py = &M::y; // pointer to member y
M *pm = &m;
int s = m.*px + pm->*py;
return s;
}
int main() {
M m;
void (M::*pf)(int, int) = &M::set_xy; // pointer to member function set_xy
(m.*pf)(10, 20); // invokes set_xy
cout << "sum = " << sum(m) << endl;
M *op = &m; // pointer to object m
(op->*pf)(30, 40); // invokes set_xy
cout << "sum = " << sum(m) << endl;
return 0;
}
CONSTRUCTOR:
A constructor is a special member function whose task is to initialize the objects of its class.
• It is special because its name is the same as the class name.
• The constructor is invoked whenever an object of its associated class is created.
• It is called constructor because it constructs the values of data members of the class.
A constructor in C++ is a special member function of a class that is automatically called when an object of that class is
created. It is responsible for initializing the object and setting its initial state.
Syntax: A constructor has the same name as the class and does not have a return type, not even void. It is declared and
defined within the class.
For example:
class MyClass {
public:
MyClass() {
// Constructor code
}
};
Initialization: The primary purpose of a constructor is to initialize the member variables of an object. It ensures that the
object starts with meaningful and valid data.
• Same name as the class: A constructor has the same name as the class in which it is defined. It is declared and
defined within the class definition.
• No return type: Constructors do not have a return type, not even void. They are automatically invoked when
an object is created and do not need to be explicitly called.
• Default constructor: If no constructor is defined in the class, the compiler provides a default constructor. It
initializes member variables with default values or leaves them uninitialized for built-in types.
• Parameterized constructors: Constructors can be defined with parameters to allow initialization of objects
with specific values. These parameterized constructors provide flexibility and allow objects to be customized
during creation.
• Overloaded constructors: A class can have multiple constructors, each with a different set of parameters. This
is known as constructor overloading. Overloaded constructors allow objects to be created in different ways,
depending on the arguments provided.
• Initialization list: Constructors can use an initialization list to initialize member variables directly. This list
appears before the constructor body and provides a more efficient way to initialize members, especially for
const or reference member variables.
• Copy constructor: The copy constructor creates a new object as a copy of an existing object of the same class.
It is used when objects are passed by value, returned by value, or initialized with another object of the same
class.
• Constructor chaining: Constructors can call other constructors of the same class, either through constructor
delegation or by using initialization lists. This allows code reuse and enables constructors to share common
initialization logic.
• Object creation: Constructors are automatically called when objects are created. They ensure that objects are
properly initialized before they are used.
A. Default Constructor:
#include <iostream>
#include <cstring> // For strcpy function
using namespace std;
class abc {
C++ | 24
private:
char nm[50]; // Specify the size of the array
public:
abc() {
cout << "Enter your name: ";
cin >> nm;
}
void display() {
cout << "Name: " << nm << endl;
}
};
int main() {
abc d;
d.display();
return 0;
}
Explanation:
1. Include Headers:
o #include <iostream> for input and output operations.
o #include <cstring> for strcpy if needed (although not used in this simple case).
2. Class Definition:
o class abc { ... }; defines a class named abc.
o The class has a private member variable nm which is a character array of size 50.
3. Default Constructor:
o abc() { ... } is the default constructor that gets called when an object of the class is created.
o It prompts the user to enter a name and stores it in the nm array.
4. Display Function:
o void display() { ... } prints the name stored in the nm array.
5. Main Function:
o int main() { ... } creates an object of the class abc, calls the default constructor, and then calls the
display method to print the name.
Output: When you run the program, it will prompt you to enter your name and then display it:
Enter your name: John
Name: John
B. PARAMETERIZED CONSTRUCTOR:
The constructors that can take arguments are called parameterized constructors. Using parameterized
constructor we can initialize the various data elements of different objects with different values when they are
created.
Example:-
#include <iostream>
using namespace std;
class Integer {
private:
int m, n;
public:
// Parameterized constructor
Integer(int x, int y) {
m = x;
n = y;
}
// Display function to print values
void display() {
cout << "m: " << m << ", n: " << n << endl;
}
};
int main() {
// Implicit call to parameterized constructor
Integer int1(0, 100);
// Explicit call to parameterized constructor
Integer int2 = Integer(25, 75);
C++ | 25
#include <iostream>
#include <cstring> // Include for strcpy
using namespace std;
class Integer {
int m, n;
public:
// Constructor declaration
Integer(int x, int y);
// Display function
void display() {
cout << "m: " << m << endl;
cout << "n: " << n << endl;
}
};
// Constructor definition
Integer::Integer(int x, int y) {
m = x;
n = y;
}
class ABC {
private:
char nm[30];
int age;
public:
// Default constructor
ABC() {}
// Parameterized constructor
ABC(char x[], int y) {
strcpy(nm, x);
C++ | 26
age = y;
}
Explanation:
1. Integer Class:
o Integer(int x, int y); declares a parameterized constructor.
o Integer::Integer(int x, int y) initializes the member variables m and n.
2. ABC Class:
o Default constructor ABC() and parameterized constructor ABC(const char x[], int y) are defined.
o strcpy(nm, x); copies the string x into nm.
o get() method prompts user input for nm and age.
o display() method prints the values of nm and age.
3. Main Function:
o Creates objects of both Integer and ABC classes, demonstrating the use of constructors.
o int1 and int2 are created using the parameterized constructor of Integer.
o l is created using the default constructor of ABC, while m uses the parameterized constructor.
o Calls to get() and display() methods demonstrate how to interact with class members.
o cin.get() is used to wait for user input before the program exits, effectively replacing getch() from
<conio.h>.
This program demonstrates the use of both default and parameterized constructors, initializing objects with different
values, and displaying those values.
D. OVERLOADED CONSTRUCTOR: -
#include <iostream>
#include <conio.h>
using namespace std;
class Sum {
private:
int a, b;
float d;
double e;
public:
C++ | 27
// Default constructor
Sum() {
cout << "Enter a: ";
cin >> a;
cout << "Enter b: ";
cin >> b;
cout << "Sum = " << a + b << endl;
}
// Parameterized constructor with two integers
Sum(int x, int y) {
a = x;
b = y;
cout << "Sum = " << a + b << endl;
}
// Parameterized constructor with an integer, a float, and a double
Sum(int x, float y, double z) {
a = x;
d = y;
e = z;
cout << "Sum = " << a + d + e << endl;
}
};
int main() {
// Clear screen - Use system("cls") or system("clear") for cross-platform support
// clrscr(); is non-standard and may not work in modern environments
system("cls"); // Clear screen for Windows
// system("clear"); // Clear screen for Unix/Linux
Sum l; // Object l created using default constructor
Sum m(20, 50); // Object m created using parameterized constructor with two integers
Sum n(3, 3.2f, 4.55); // Object n created using parameterized constructor with an integer, a float, and
a double
getch(); // Wait for a key press before exiting
return 0;
}
Explanation:
1. Default Constructor:
o Prompts the user to input values for a and b and displays their sum.
2. Parameterized Constructor with Two Integers:
o Initializes a and b with the given values and displays their sum.
3. Parameterized Constructor with Integer, Float, and Double:
o Initializes a, d, and e with the given values and displays their sum.
4. Main Function:
o Clears the screen using system("cls").
o Creates objects l, m, and n using different constructors and displays the sums.
o Waits for a key press before exiting the program.
E. COPY CONSTRUCTOR:
#include <iostream>
using namespace std;
class code {
int id;
public:
// Default constructor
code() {}
// Parameterized constructor
code(int a) {
id = a;
}
// Copy constructor
code(const code &x) {
id = x.id;
}
C++ | 28
// Display function
void display() {
cout << id;
}
};
int main() {
code A(100); // Parameterized constructor
code B(A); // Copy constructor
code C = A; // Copy constructor
code D; // Default constructor
D = A; // Assignment operator
cout << "\nId of A: ";
A.display();
cout << "\nId of B: ";
B.display();
cout << "\nId of C: ";
C.display();
cout << "\nId of D: ";
D.display();
return 0;
}
Output:
Id of A: 100
Id of B: 100
Id of C: 100
Id of D: 100
Explanation:
1. Class Definition:
o Default Constructor: Initializes an object without parameters.
o Parameterized Constructor: Initializes an object with a given value.
o Copy Constructor: Initializes a new object as a copy of an existing object.
o Display Function: Displays the value of the id.
2. Main Function:
o code A(100); initializes object A using the parameterized constructor.
o code B(A); initializes object B using the copy constructor.
o code C = A; initializes object C using the copy constructor.
o code D; initializes object D using the default constructor.
o D = A; assigns the value of A to D using the assignment operator.
o Calls to display() print the values of id for each object.
F. DYNAMIC CONSTRUCTOR: -
#include <iostream>
#include <cstring> // Included for strlen() and strcpy() functions
class String {
char *name;
int length;
public:
// Default constructor
String() {
length = 0;
name = new char[length + 1]; // One extra for '\0'
name[0] = '\0'; // Initialize with an empty string
}
// Parameterized constructor
String(const char *s) {
length = strlen(s);
name = new char[length + 1];
C++ | 29
strcpy(name, s);
}
// Destructor to release allocated memory
~String() {
delete[] name;
}
void display() const {
std::cout << name << std::endl;
}
// Member function to concatenate two strings
void join(const String &a, const String &b) {
length = a.length + b.length;
delete[] name;
name = new char[length + 1]; // Dynamic allocation
strcpy(name, a.name);
strcat(name, b.name);
}
};
int main() {
const char *first = "Joseph"; // Changed to const char*
String name1(first), name2("Louis"), name3("LaGrange"), s1, s2;
s1.join(name1, name2);
s2.join(s1, name3);
name1.display();
name2.display();
name3.display();
s1.display();
s2.display();
return 0;
}
Output:
Joseph
Louis
LaGrange
JosephLouis
JosephLouisLaGrange
Explanation:
1. Class Definition:
o Default Constructor: Initializes an object with an empty string.
o Parameterized Constructor: Initializes an object with a given C-string.
o Destructor: Releases the allocated memory when the object is destroyed.
o display(): Displays the stored string.
o join(): Concatenates two strings and stores the result in the current object.
2. Main Function:
o const char *first = "Joseph"; initializes a C-string.
o String name1(first), name2("Louis"), name3("LaGrange"), s1, s2;
creates objects using parameterized and default constructors.
o s1.join(name1, name2); concatenates name1 and name2, and stores the result in
s1.
o s2.join(s1, name3); concatenates s1 and name3, and stores the result in s2.
o Calls to display() print the stored strings for each object.
C++ | 30
DESTRUCTOR:-
• A destructor in C++ is a special member function of a class that is automatically called when an object of that
class is destroyed.
• It is responsible for performing cleanup tasks and releasing resources allocated by the object during its lifetime.
Name and syntax: A destructor is named with the class name preceded by a tilde (~). It has the same name as the class
and is defined within the class declaration.
• A destructor never takes any argument nor does it return any value.
• It will be invoked implicitly by the compiler upon exit from the program to clean up storage that is no longer
accessible.
• It is a good practice to declare destructor in a program since it releases memory space for future use.
• Delete is used to free memory which is created by new.
For example:
class MyClass {
public:
// Constructor and member functions
~MyClass() {
// Destructor code
}
};
• A destructor, us the name implies is used to destroy the objects that have been created by a constructor.
• Like a constructor, the destructor is a member function whose name is the same as the class name but is
preceded by a tilde.
For Example:-
~ integer( ) { }
Automatic invocation: Destructors are automatically invoked when an object is destroyed. This happens when the
object goes out of scope (for stack-allocated objects) or when the delete operator is used to deallocate dynamically
allocated objects.
• No return type or parameters: Destructors do not have a return type, not even void, and they do not take any
parameters. They are called implicitly and do not need to be explicitly called by the programmer.
• Resource cleanup: The primary purpose of a destructor is to release resources held by the object. This can
include deallocating dynamic memory, closing open files, releasing network connections, or any other
necessary cleanup operations.
• User-defined destructors: If a class requires specific cleanup operations, the programmer can define a
destructor. This allows the class to release resources and perform custom cleanup tasks. If no destructor is
explicitly defined, the compiler generates a default destructor.
• Order of destructor invocation: In a class hierarchy, destructors are called in reverse order of object
construction. This means that the destructor of the most derived class is called first, followed by destructors of
base classes in the reverse order of their inheritance.
• Virtual destructors: When a class is designed to be used as a base class, its destructor should be declared as
virtual. This ensures that the proper destructor is called when deleting objects through a base class pointer or
reference, allowing for correct cleanup of derived class resources.
• Exception handling: Destructors can handle exceptions thrown during the cleanup process to ensure that
resources are properly released, even in exceptional situations. This allows for robust and reliable cleanup of
resources.
• Destructors are an important part of C++ classes as they ensure proper cleanup and resource management.
They release resources held by objects and allow for graceful termination of objects' lifetimes. By defining a
destructor, you can explicitly control the cleanup process and ensure the release of resources in a timely
manner.
Example:-
matrix : : ~ matrix( )
{
for(int i=0; i<11;i++)
delete p[i];
delete p;
}
C++ | 31
IMPLEMENTED OF DESTRUCTORS:-
#include <iostream>
using namespace std;
class Matrix {
int rows, cols;
int **p;
public:
// Parameterized constructor
Matrix(int r, int c) : rows(r), cols(c) {
p = new int*[rows];
for (int i = 0; i < rows; i++) {
p[i] = new int[cols];
}
cout << "Matrix created" << endl;
}
// Destructor
~Matrix() {
for (int i = 0; i < rows; i++) {
delete[] p[i];
}
delete[] p;
cout << "Matrix destroyed" << endl;
}
// Function to set matrix elements
void setElement(int i, int j, int value) {
if (i >= 0 && i < rows && j >= 0 && j < cols) {
p[i][j] = value;
}
}
// Function to display matrix elements
void display() const {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << p[i][j] << " ";
}
cout << endl;
}
}
};
int main() {
// Creating a matrix object with dynamic memory allocation
Matrix mat(3, 3);
// Setting values for the matrix
mat.setElement(0, 0, 1);
mat.setElement(0, 1, 2);
mat.setElement(0, 2, 3);
mat.setElement(1, 0, 4);
mat.setElement(1, 1, 5);
mat.setElement(1, 2, 6);
mat.setElement(2, 0, 7);
mat.setElement(2, 1, 8);
mat.setElement(2, 2, 9);
// Displaying the matrix
mat.display();
// Matrix object is automatically destroyed when it goes out of scope
return 0;
}
Output:
Matrix created
123
456
789
C++ | 32
Matrix destroyed
1. Class Definition:
o The Matrix class has a parameterized constructor that dynamically allocates memory
for a 2D array based on the provided number of rows and columns.
o The destructor deallocates the memory to prevent memory leaks.
2. Constructor:
o The constructor initializes the matrix by allocating memory for each row and each
column.
3. Destructor:
o The destructor iterates through each row and deallocates the memory for each
column. Then, it deallocates the memory for the row pointers.
4. Member Functions:
o setElement: Sets a specific element in the matrix.
o display: Displays the matrix elements.
5. Main Function:
o A Matrix object is created and manipulated. When the program ends or the object
goes out of scope, the destructor is automatically called, releasing the allocated
memory.
OPERATOR OVERLOADING:-
• Operator overloading in C++ refers to the ability to redefine the behavior of operators when applied to user-
defined types or objects.
• It allows you to provide custom implementations for operators, such as +, -, *, /, <, >, =, etc., for your classes.
• By overloading operators, you can make your code more intuitive, expressive, and closely resemble the natural
behavior of the operators.
Syntax: Operator overloading is accomplished by defining special member functions or non-member functions called
operator functions. These functions have the keyword operator followed by the operator symbol. For example, operator+
for overloading the addition operator.
• Class member or non-member functions: Operator functions can be defined as member functions of a class
or as non-member functions. Member functions are called on the left-hand operand, while non-member
functions take two operands as parameters.
• Overloadable operators: Not all operators can be overloaded in C++. Some operators, such as the scope
resolution operator (::) and the ternary conditional operator (?:), cannot be overloaded. The operators that can be
overloaded include arithmetic, relational, logical, assignment, bitwise, and more.
• Unary and binary operators: Operators can be unary or binary. Unary operators have a single operand, while
binary operators have two operands. The number of parameters required for an operator function depends on
the arity of the operator.
• Return type and arguments: Operator functions have a return type that defines the result of the operation. The
arguments of operator functions depend on the operands involved in the operation. For binary operators, one
operand is passed implicitly, and the other is explicitly provided.
• Implicit and explicit conversions: Operator overloading can involve implicit or explicit conversions. Implicit
conversions allow the operands to be automatically converted to the required type, while explicit conversions
require the use of explicit casting.
• Limitations and best practices: Operator overloading should be used judiciously and with care. Overloading
operators should adhere to logical and intuitive behaviors to avoid confusion and maintain code readability. It is
recommended to follow established conventions and behaviors associated with operators.
• Common examples: Operator overloading can be used to perform mathematical operations on custom classes,
concatenate strings using the addition operator, compare objects using relational operators, perform I/O
operations with stream insertion and extraction operators, and more.
C++ | 33
• Operator overloading provides a powerful mechanism to extend the capabilities of your classes and make
your code more expressive. By redefining the behavior of operators, you can write code that closely resembles
the intended logic or behavior, improving code readability and making it more intuitive to work with user-
defined types.
Operator overloading provides a flexible option for the creation of new definations for most of the C++ operators.
A basic difference between them is that a friend function will have only one argument for unary operators
and two for binary operators, this is because the object used to invoke the member function is passed
implicitly and therefore is available for the member functions. Arguments may be either by value or by
reference. operator functions are declared in.
the class using prototypes as follows:-
• vector operator + (vector); // vector addition
• vector operator-( ); //unary minus
• friend vector operator + (vector, vector); // vector add friend
• vector operator -(vector); // unary minus
• vector operator - ( vector &a); // subtraction
• int operator = =(vector); //comparison
• friend int operator = =(vector ,vrctor); // comparison
vector is a data type of class and may represent both magnitude and direction or a series of points called elements.
#include<iostream>
using namespace std;
class abc {
int m, n;
public:
abc() {
C++ | 34
m = 8;
n = 9;
}
void show() {
cout << m << n << endl;
}
// Overloading unary -- operator as a member function
void operator--() {
--m;
--n;
}
};
int main() {
abc x;
x.show(); // Output: 89
--x;
x.show(); // Output: 78
return 0;
}
In this code:
#include <iostream>
using namespace std;
class abc {
int m, n;
public:
abc() {
m = 8;
n = 9;
}
void show() {
cout << m << n;
}
friend void operator--(abc &p); // Declaration of operator-- as a friend function
};
// Definition of the operator-- function
void operator--(abc &p) {
--p.m;
--p.n;
}
int main() {
abc x;
x.show(); // Output: 89
--x;
x.show(); // Output: 78
return 0;
}
C++ | 35
In this code:
Unary operator+ for adding two complex numbers (using member function)
#include <iostream>
using namespace std;
class complex {
float real, img;
public:
complex() {
real = 0;
img = 0;
}
complex(float r, float i) {
real = r;
img = i;
}
void show() {
cout << real << "+i" << img;
}
friend complex operator+(const complex &p, const complex &q);
};
complex operator+(const complex &p, const complex &q) {
complex result;
result.real = p.real + q.real;
result.img = p.img + q.img;
return result;
}
int main() {
complex s(3, 4);
complex t(4, 5);
complex m = s + t; // Using overloaded + operator
s.show(); cout << ", ";
t.show(); cout << ", ";
m.show();
return 0;
}
Unary operator+ for adding two complex numbers (using friend function)
adding two complex numbers using a friend function for overloading the unary + operator is mostly
correct. However, there are a few corrections needed. Let's fix them:
1. The operator+ function should be declared as a friend inside the class definition.
2. The operator+ function should be defined outside the class definition.
3. The main function should be corrected to use the overloaded + operator correctly.
C++ | 36
#include <iostream>
using namespace std;
class complex {
float real, img;
public:
complex() {
real = 0;
img = 0;
}
complex(float r, float i) {
real = r;
img = i;
}
void show() {
cout << real << "+i" << img;
}
Changes made:
This code will correctly add two complex numbers using the unary + operator.
Type conversions: also known as type casting, allow you to convert values from one type to another. In C++, there
are several types of type conversions available, including implicit and explicit conversions, as well as user-defined
conversions. Let's break down these concepts:
C++ | 37
Implicit Conversions: Implicit conversions are performed automatically by the compiler when it can safely convert
one type to another without any loss of information.
For example:
int num = 5;
double decimal = num; // Implicit conversion from int to double
Explicit Conversions: Explicit conversions, also known as type casts, are performed manually by the programmer
using specific syntax. There are four explicit type cast operators available in C++:
Static Cast: Performs a wide range of conversions that are known to be safe by the programmer.
Dynamic Cast: Used in polymorphic class hierarchies to safely convert pointers or references between base and
derived classes at runtime.
Base* basePtr = new Derived();
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // Explicit dynamic_cast from Base*
to Derived*
Const Cast: Removes the const or volatile qualifier from a variable, allowing modifications.
const int num = 5;
int* ptr = const_cast<int*>(&num); // Explicit const_cast to remove const qualifier
*ptr = 10; // Modifying a const variable using const_cast (avoid doing this in practice)
Reinterpret Cast: Performs low-level conversions between unrelated types, such as converting a pointer to an
integer or vice versa.
int num = 42;
int* numPtr = reinterpret_cast<int*>(&num); // Explicit reinterpret_cast from int to int*
User-Defined Conversions:
You can define your own conversion functions in a class to enable type conversions between user-defined types. These
conversions can be explicit or implicit, depending on how you define them.
Type Promotion and Demotion:
C++ automatically promotes or demotes values of smaller types to larger types when performing operations. For
example, if you add an int and a float, the int will be promoted to a float before the addition. Similarly, if you assign a
larger type to a smaller type, the value may be truncated or rounded.
Standard Type Conversions:
C++ provides standard conversions for certain situations, such as converting arithmetic types to bool, converting
arithmetic types to strings using std::to_string(), and vice versa.
In mixed expressions where constants and variables are of different data types, the assignment operation causes
automatic type conversion between the operands according to certain rules. The type of data to the right of an
assignment operator is automatically converted to the data type of the variable on the left.
For example:
int x;
float y = 20.123;
x = y; // This converts float variable y to an integer before its value is assigned to x
These conversions can involve built-in types, as well as user-defined types. When dealing with objects of different
classes, explicit type conversion methods like constructors or casting operators may be used to perform the conversion.
Each type of conversion has its own set of rules and considerations, ensuring safe and effective data manipulation in
C++ programs.