0% found this document useful (0 votes)
16 views19 pages

Unit-5 1

The document provides an overview of constructors in C++, detailing their characteristics and types, including default, parameterized, copy, and move constructors. It also covers operator overloading, type conversion, inheritance types (public, protected, private), and function overriding, explaining their significance and providing code examples for clarity. Key concepts such as implicit and explicit type conversions, as well as compile-time and runtime polymorphism, are highlighted throughout the text.

Uploaded by

Yash Agarwal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views19 pages

Unit-5 1

The document provides an overview of constructors in C++, detailing their characteristics and types, including default, parameterized, copy, and move constructors. It also covers operator overloading, type conversion, inheritance types (public, protected, private), and function overriding, explaining their significance and providing code examples for clarity. Key concepts such as implicit and explicit type conversions, as well as compile-time and runtime polymorphism, are highlighted throughout the text.

Uploaded by

Yash Agarwal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Unit-5

Constructors and their types


Constructor in C++ is a special member function that is automatically invoked when an object
of the class is created. It is used to initialize the data members of new objects generally. The
constructor in C++ has the same name as the class and does not have a return type.
It constructs the values i.e. provides data for the object which is why it is known as a
constructor.
Characteristics of Constructors in C++
• The name of the constructor is the same as its class name.
• Constructors are mostly declared in the public section of the class though they can be
declared in the private section of the class.
• Constructors do not return values; hence they do not have a return type.
• A constructor gets called automatically when we create the object of the class.
Types of Constructor in C++
1. Default Constructor: No parameters. It initializes the object with default values.
3. Parameterized Constructor: Takes parameters and allows the programmer to initialize
the object with specific values.
4. Copy Constructor: Takes a reference to another object of the same class. Used to
create a copy of an object.
Note: Just like the default constructor, the C++ compiler also provides an implicit copy
constructor if the explicit copy constructor definition is not present.
Here, it is to be noted that, unlike the default constructor where the presence of any
type of explicit constructor results in the deletion of the implicit default constructor,
the implicit copy constructor will always be created by the compiler if there is no
explicit copy constructor or explicit move constructor is present.
5. Move Constructor: It is a specialized constructor introduced in C++11 to optimize the
transfer of resources, especially in cases where temporary objects or dynamically
allocated resources are involved. Takes an rvalue reference to another object. Transfers
resources from a temporary object.

• A move constructor transfers ownership of resources from one object to another,


avoiding the cost of deep copying.
• The source object (temporary or otherwise) is left in a valid but unspecified state
after the move.
• It is triggered when an object is initialized using an rvalue reference (e.g.,
std::move(obj)).
Purpose of Move Constructor:
Avoid expensive deep copies for temporary objects.
Improve performance in scenarios like returning large objects from functions.
Example 1:
#include <iostream>
using namespace std;
class Demo {
int x, y;
public:
// Default Constructor
Demo() {
x = 0;
y = 0;
cout << "Default Constructor Called\n";
}
// Parameterized Constructor
Demo(int a, int b) {
x = a;
y = b;
cout << "Parameterized Constructor Called\n";
}
// Copy Constructor
Demo(const Demo& obj) {
x = obj.x;
y = obj.y;
cout << "Copy Constructor Called\n";
}

// Function to display values


void display() {
cout << "x: " << x << ", y: " << y << endl;
}
};

int main() {
Demo obj1; // Default Constructor
obj1.display();

Demo obj2(10, 20); // Parameterized Constructor


obj2.display();

Demo obj3 = obj2; // Copy Constructor


obj3.display();

return 0;
}
Output:
Default Constructor Called
x: 0, y: 0
Parameterized Constructor Called
x: 10, y: 20
Copy Constructor Called
x: 10, y: 20

Example 2: Move Constructor


#include <iostream>
using namespace std;
class Demo {
int* data;
public:
// Constructor
Demo(int value) {
data = new int(value);
cout << "Constructor Called\n";
}
// Move Constructor
Demo(Demo&& obj) noexcept {
data = obj.data; // Transfer ownership
obj.data = nullptr; // Nullify source object
cout << "Move Constructor Called\n";
}
// Destructor
~Demo() {
if (data) {
cout << "Destructor Called, Value: " << *data << endl;
delete data;
} else {
cout << "Destructor Called for Null Object\n";
}
}
// Display Value
void display() const {
if (data)
cout << "Value: " << *data << endl;
else
cout << "Data is Null\n";
}
};
int main() {
Demo obj1(42); // Constructor
Demo obj2 = std::move(obj1); // Move Constructor
obj1.display(); // Data is Null
obj2.display(); // Value: 42
return 0;
}
Output:
Constructor Called
Move Constructor Called
Data is Null
Value: 42
Destructor Called for Null Object
Destructor Called, Value: 42

Operator Overloading
In C++, Operator overloading is a compile-time polymorphism.
For example, we can overload an operator ‘+’ in a class like String so that we can concatenate
two strings by just using +. Other example classes where arithmetic operators may be
overloaded are Complex Numbers, Fractional Numbers, Big integers, etc.
If the user wants to make the operator “+” add two class objects, the user has to redefine the
meaning of the “+” operator such that it adds two class objects. This is done by using the
concept of “Operator overloading”. So the main idea behind “Operator overloading” is to use
C++ operators with class variables or class objects. Redefining the meaning of operators really
does not change their original meaning; instead, they have been given additional meaning
along with their existing ones.
// Operator Overloading
#include <iostream>
using namespace std;
class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i = 0)
{
real = r;
imag = i;
}
// This is automatically called when '+' is used with between two Complex objects
Complex operator+(Complex const& obj)
{
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() { cout << real << " + i" << imag << '\n'; }
};
int main()
{
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2;
c3.print();
}
Output
12 + i9
Important Points about Operator Overloading
1) For operator overloading to work, at least one of the operands must be a user-defined class
object.
2) Assignment Operator: Compiler automatically creates a default assignment operator with
every class. The default assignment operator does assign all members of the right side to the
left side and works fine in most cases (this behavior is the same as the copy constructor).
3) Conversion Operator: We can also write conversion operators that can be used to convert
one type to another type. Overloaded conversion operators must be a member method. Other
operators can either be the member method or the global method.

4) Any constructor that can be called with a single argument works as a conversion
constructor, which means it can also be used for implicit conversion to the class being
constructed

Type Conversion in C++


Type conversion refers to converting a data type into another. C++ supports both implicit and
explicit type conversions.
1. Implicit Type Conversion (Type Promotion)
• Also known as type coercion.
• Performed automatically by the compiler.
• Occurs when data of a smaller type is assigned to a larger type.
• Examples:
o int to float
o float to double
Example:
int a = 10;
double b = a; // Implicit conversion from int to double
2. Explicit Type Conversion (Type Casting)
• Also known as type casting.
• Performed manually by the programmer.
• Syntax:
o C-style casting: (type)value
o Function-style casting: type(value)
o C++ casting operators (introduced for safety):
▪ static_cast
▪ dynamic_cast
▪ const_cast
▪ reinterpret_cast
Example:
int a = 10;
double b = (double)a; // C-style casting
double c = static_cast<double>(a); // C++-style casting

public, protected and private inheritance in C++


• public inheritance makes public members of the base class public in the derived class, and
the protected members of the base class remain protected in the derived class.
• protected inheritance makes the public and protected members of the base class protected
in the derived class.
• private inheritance makes the public and protected members of the base class private in the
derived class.

Note: private members of the base class are inaccessible to the derived class.

Example 1: C++ public Inheritance

// C++ program to demonstrate the working of public inheritance


#include <iostream>

using namespace std;

class Base {

private:

int pvt = 1;

protected:

int prot = 2;

public:

int pub = 3;

// function to access private member

int getPVT() {

return pvt;

};

class PublicDerived : public Base {

public:

// function to access protected member from Base

int getProt() {

return prot;

};

int main() {

PublicDerived object1;

cout << "Private = " << object1.getPVT() << endl;

cout << "Protected = " << object1.getProt() << endl;

cout << "Public = " << object1.pub << endl;

return 0;

Output
Private = 1

Protected = 2

Public = 3

Here, we have derived PublicDerived from Base in public mode.

As a result, in PublicDerived:

• prot is inherited as protected.

• pub and getPVT() are inherited as public.

• pvt is inaccessible since it is private in Base.

• Since private and protected members are not accessible


from main() , we need to create public
functions getPVT() and getProt() to access them:

• // Error: member "Base::pvt" is inaccessible


• cout << "Private = " << object1.pvt;

• // Error: member "Base::prot" is inaccessible
• cout << "Protected = " << object1.prot;

• Accessibility in public Inheritance


Accessibility private members protected members public members

Base Class Yes Yes Yes

Derived Class No Yes Yes

Example 2: C++ protected Inheritance

// C++ program to demonstrate the working of protected inheritance


#include <iostream>
using namespace std;
class Base {
private:
int pvt = 1;
protected:
int prot = 2;
public:
int pub = 3;
// function to access private member
int getPVT() {
return pvt;
}
};
class ProtectedDerived : protected Base {
public:
// function to access protected member from Base
int getProt() {
return prot;
}
// function to access public member from Base
int getPub() {
return pub;
}
};

int main() {
ProtectedDerived object1;
cout << "Private cannot be accessed." << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Run Code

Output

Private cannot be accessed.


Protected = 2
Public = 3

Here, we have derived ProtectedDerived from Base in protected mode.


As a result, in ProtectedDerived :

• prot , pub and getPVT() are inherited as protected.


• pvt is inaccessible since it is private in Base .

As we know, protected members cannot be directly accessed from outside


the class. As a result, we cannot use getPVT() from ProtectedDerived .

That is also why we need to create the getPub() function in ProtectedDerived in


order to access the pub variable.

// Error: member "Base::getPVT()" is inaccessible


cout << "Private = " << object1.getPVT();
// Error: member "Base::pub" is inaccessible
cout << "Public = " << object1.pub;

Accessibility in protected Inheritance


private protected
Accessibility public members
members members

Base Class Yes Yes Yes

Derived Yes (inherited as


No Yes
Class protected variables)

Example 3: C++ private Inheritance

// C++ program to demonstrate the working of private inheritance

#include <iostream>

using namespace std;

class Base {

private:

int pvt = 1;

protected:

int prot = 2;

public:

int pub = 3;
// function to access private member

int getPVT() {

return pvt;

};

class PrivateDerived : private Base {

public:

// function to access protected member from Base

int getProt() {

return prot;

// function to access private member

int getPub() {

return pub;

};

int main() {

PrivateDerived object1;

cout << "Private cannot be accessed." << endl;

cout << "Protected = " << object1.getProt() << endl;

cout << "Public = " << object1.getPub() << endl;

return 0;

Run Code

Output

Private cannot be accessed.

Protected = 2
Public = 3

Here, we have derived PrivateDerived from Base in private mode.

As a result, in PrivateDerived:

• prot, pub and getPVT() are inherited as private.

• pvt is inaccessible since it is private in Base.

As we know, private members cannot be directly accessed from outside the class. As a result, we
cannot use getPVT() from PrivateDerived.

That is also why we need to create the getPub() function in PrivateDerived in order to access
the pub variable.

// Error: member "Base::getPVT()" is inaccessible

cout << "Private = " << object1.getPVT();

// Error: member "Base::pub" is inaccessible

cout << "Public = " << object1.pub;

Accessibility in private Inheritance

private
Accessibility protected members public members
members

Base Class Yes Yes Yes

Derived Yes (inherited as Yes (inherited as


No
Class private variables) private variables)

Function Overriding in C++


A function is a block of statements that together performs a specific task by taking some input and
producing a particular output. Function overriding in C++ is termed as the redefinition of base class
function in its derived class with the same signature i.e. return type and parameters. It can be of
both type: Compile Time and Runtime Polymorphism.

Real-Life Example of Function Overriding

The best Real-life example of this concept is the Constitution of India. India took the political code,
structure, procedures, powers, and duties of government institutions and set out fundamental rights,
directive principles, and the duties of citizens of other countries and implemented them on its own;
making it the biggest constitution in the world.
Another Development real-life example could be the relationship between RBI(The Reserve Bank of
India) and Other state banks like SBI, PNB, ICICI, etc. Where the RBI passes the same regulatory
function and others follow it as it is.

Compile Time Function Overriding

In compile time function overriding, the function call and the definition is binded at the compilation
of the program. Due to this, it is also called early binding or static binding.

class Parent {

access_modifier :

// overridden function

return_type name_of_the_function() {}

};

class child : public Parent {

access_modifier :

// overriding function

return_type name_of_the_function() {}

};

Runtime Function Overriding using Virtual Function

Unlike other languages like Java, the function overriding in C++ can be performed at both compile
time and runtime. In all the above examples, the call to the overridden function is resolved during
compile time. It is also called early binding where the function call is binded to its definition during
compilation.

Function overriding can also be performed at the runtime, which means that function call will be
binded to its definition during runtime (also known as late binding or dynamic binding). This can be
done with the help of virtual functions.

class Base {
public:

virtual func()

// definition

};

class Derived : public Base {

public:

func() override

// new definition

};

Here, override keyword tells the compiler that the given overridden function should be declared as
virtual in the parent class. It is a kind of double check as the program can compile without errors
even if the function is not virtual. But then, it will be compile time polymorphism and we won’t get
the desired behaviour of the function overriding.

Virtual base class in C++


Virtual base classes are used in virtual inheritance in a way of preventing multiple “instances” of a
given class appearing in an inheritance hierarchy when using multiple inheritances.

Need for Virtual Base Classes: Consider the situation where we have one class A . This class A is
inherited by two other classes B and C. Both these class are inherited into another in a new class D as
shown in figure below.
As we can see from the figure that data members/function of class A are inherited twice to class D.
One through class B and second through class C. When any data / function member of class A is
accessed by an object of class D, ambiguity arises as to which data/function member would be
called? One inherited through B or the other inherited through C. This confuses compiler and it
displays error.

#include <iostream>

using namespace std;

class A {

public:

int a;

A() // constructor

a = 10;

};

class B : public virtual A {

};

class C : public virtual A {


};

class D : public B, public C {

};

int main()

D object; // object creation of class d

cout << "a = " << object.a << endl;

return 0;

Pointer
Pointers are symbolic representation of addresses. The pointer in C++ language is a variable, it is also
known as locator or indicator that points to an address of a value.

Pointers with Constant


When a pointer is made constant then it is not possible to modify the address stored inside that
pointer. However, we can modify the value stored into that address.

Syntax:

Datatype *const <pointer-name>=address;

Pointer to constant integer

Here the variable being declared is a pointer, pointing to a constant integer. Effectively, this implies
that the pointer is pointing to a value that shouldn’t be changed. Const qualifier doesn’t affect the
pointer in this scenario so the pointer is allowed to point to some other address.
Syntax:

const datatype *<pointer-name>=address;

Or

datatype const *<pointer-name>=address;

Array of Objects
An array of objects in C++ is a collection of objects of the same class. It allows you to manage multiple
objects efficiently, just as arrays help manage collections of primitive data types.

An array of objects is used when you need to manage a collection of objects of the same class type.
Instead of creating multiple individual objects manually, an array allows you to:

1. Store and manage multiple objects efficiently.

2. Access objects using an index for easier traversal and operations.

3. Reduce redundancy and simplify code when dealing with a fixed number of objects.

An array of objects is suitable for scenarios where you have to manage a group of similar entities (eg:
Student Records), Fixed Number of Items (eg. Product Inventory), Processing Batch Operations.

#include <iostream>

using namespace std;

class Product {

int id;

string name;

float price;

public:

void setDetails(int pid, string pname, float pprice) {

id = pid;

name = pname;

price = pprice;

void displayDetails() {

cout << "ID: " << id << ", Name: " << name << ", Price: $" << price << endl;

};

int main() {

const int SIZE = 3; // Fixed number of products


Product products[SIZE]; // Array of objects

// Set details for products

products[0].setDetails(101, "Laptop", 750.50);

products[1].setDetails(102, "Phone", 350.00);

products[2].setDetails(103, "Tablet", 200.25);

// Display product details

cout << "Product Inventory:\n";

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

products[i].displayDetails();

return 0;

Output:

Product Inventory:

ID: 101, Name: Laptop, Price: $750.5

ID: 102, Name: Phone, Price: $350

ID: 103, Name: Tablet, Price: $200.25

You might also like