OOPs Concept In C++ | A Detailed Guide With Codes & Explanations
Object-oriented programming (OOP) is a fundamental paradigm in computer science that enables developers to design and structure their code more efficiently and intuitively. C++, a powerful and versatile programming language, is known for its strong support of OOP concepts. In a nutshell, the OOPs concept in C++ enables you to programmatically design an environment where objects interact just like they would in the actual world. It's a way of writing software that reflects the natural way of understanding and describing things and actions.
In this article, we'll explore the key OOP concepts in C++ and understand how they enhance code organization, code readability, code reusability, and code maintainability.
Why Do You Need Object-Oriented Programming (OOP) In C++?
In software development, object-oriented programming (OOP) is a vital paradigm utilized extensively, given the number of advantages. Here are a few reasons why OOP in C++ programming is a crucial tool for creating flexible programs and complex applications.
Code Reuse: One of the main benefits of using object-oriented features in programming is its ability to encourage code reuse.
- Developers can utilize the OOPs concept in C++ to build reusable classes and objects that can be applied to several projects.
- This reusability further promotes the ability to develop code more quickly and with less code duplication, i.e., efficient development.
For example: Think of a software development company that creates numerous applications. Using the class OOPs concept in C++ (and other languages), they can develop a library of classes to carry out common/ repetitive tasks like managing user authentication or database connectivity. They can then reuse these classes in numerous projects, saving a lot of time and effort.
Code Organization: The OOPS concept in C++ offers a systematic method of arranging code. Since classes and objects reflect actual entities and their relationships, the codebase is easier to understand and manage even as projects get bigger and more complicated.
- For example, the OOPS concept in C++ is used in modern video games where game elements like characters, weapons, locations, etc., are modelled in the form of objects.
- This strategy encourages collaborative creation, improves code organization, and makes code maintenance simple.
There are many other benefits of OOP in C++ that make it essential for creating modern software.
- It encourages modularity, makes code administration easier, and encourages code reuse.
- Inheritance, polymorphism, encapsulation and other OOPS concepts in C++ are the tools programmers need to build adaptable, scalable, and maintainable software systems.
- Programmers can effectively solve complicated problems and create reliable applications for a variety of industries, such as gaming, banking, healthcare, etc.
OOPs Concepts In C++ With Examples
Objects and classes are the building blocks for object-oriented programming that help implement real-world entities in programming languages. The five main pillars of OOPs in C++ are:
- Class and object
- Inheritance
- Polymorphism
- Abstraction
- Encapsulation
In the sections ahead, we will learn about these and a few other important concepts of OOP in C++ programming.
The Class OOPs Concept In C++
A class can be referred to as a collection of objects. It is the key idea behind the OOPS concept in C++ that enables you to create various user-defined data types.
- A class acts as a blueprint for objects by specifying how these objects should be constructed and how they should behave.
- A class encapsulates data members (attributes or properties) and member functions (methods or operations) that manipulate the data.
In other words, one of the primary benefits of classes is that they act like a template for building objects, where objects are instances of that class. Each object has a unique set of data members and is capable of carrying out operations.
Let's understand this OOPs concept in C++ with a real-life analogy-
Take a Student class as a template for the representation of real students who are its objects. The attributes would include name, age, and major. Methods like get_gpa and enroll_in_course may be used to enable instances of the class to enrol in courses and check their GPAs, respectively.
This class collects information on the activities of students, encouraging well-organized and reusable code in educational systems. Here, we can establish a single class containing common characteristics rather than defining a new class for each type of student. This way, classes act as user-defined data types for creating objects with similar features.
Syntax to Declare a Class in C++
Class className{
Access_specifier
Data members
Member functions
}
Here,
- Class: It is the keyword to define the class in C++
- Access_specifier: An access controller is used to control the visibility of the class data, which can be private, public, and protected. We will discuss these in a section later.
- Data members: These are variables that hold the data related to the object of the class
- Member functions: These are methods that operate on data members and specify specific behaviour of the object. (They are defined just like regular functions in C++, but since they are a part of a specific class and work on that class's objects, they are referred to as member functions.)
Code Example:
Output:
Aayush has enrolled in Programming 101
Aayush's GPA is 3.8
Explanation:
- We begin this example by including the <iostream> library for input/output operations and the namespace std directive to avoid needing std:: prefixes.
- Then, we declare a class named Student, containing 3 data members (i.e., attributes), name, age, and major, which are of data type string, int, and string, respectively.
- As mentioned in code comments, we also define two member functions (or methods) in the class, i.e., enroll_in_course() and get_gpa(), both of which print attributes of an object using the cout command.
- In the main() function, we create an object of the Student class, called aayush, representing a student entity.
- Next, we assign values to the attributes of the aayush object using the dot operator, initializing name with Aayush and age with 20.
- After that, we call the enroll_in_course() method on the object aayush with the argument (string value)- "Programming 101", resulting in a message indicating the enrollment.
- Similarly, we call the get_gpa() method, thus printing a message about the GPA.
- Finally, the main() function terminates with a return 0 statement indicating successful execution without any errors.
NOTE- Here, the class defines the structure and behaviour for creating student objects. It bundles related data and actions together. In the main function, we created the object of the Student class and assigned values to it. Then, we invoked the methods of the class using an object and printed to the console.
The Object OOPs Concept In C++
The concept of object is a core idea in object-oriented programming (OOP), which is a self-contained element with certain attributes and behaviours. It is an instance of a class that serves as a model or template for building multiple objects of similar nature.
In other words, an object combines data (attributes) and the functions that operate on that data into a single unit. These functions, often called methods, will allow the object to perform actions and manipulate its data. This bundling of data and methods within an object in large software systems supports code reuse and simpler maintenance.
Let's understand this OOPs concept in C++ with a real-life analogy-
Consider creating a class called BankAccount to represent a bank account. Each bank account will have attributes like an account number, account holder name, and balance. It will also have behaviours like depositing and withdrawing money. This clarifies the data/ attribute elements and methods of an object (bank account).
Syntax to Define Object in C++
Class_name Object_name;
Here,
- Class_name: It is the name of the class for which the object is created
- Object_name: It is the name of the object, which should be meaningful and enhance the code's readability.
Code Example:
Output:
Deposited INR500 into the account. New balance: INR1500
Withdrawn INR200 from the account. New balance: INR1300
Deposited INR100 into the account. New balance: INR600
Invalid withdrawal amount or insufficient balance.
Account 1 balance: INR1300
Account 2 balance: INR600
Explanation:
- In the C++ program above, we define a class called BankAccount to represent a bank account.
- This class has three data members: the accountNumber (int type), accountHolderName (string type), and balance (double type), which represent different attributes of the account.
- The constructor BankAccount is defined to initialize the account when an object is created. It takes initial values for account number, account holder name, and balance as parameters.
- There are two member functions with void return type, i.e., deposit() and withdraw() allow us to interact with the bank account by depositing and withdrawing money.
- These functions use an if-else statement to perform validation checks on account balance and the addition/ subtraction assignment operator to add or subtract amounts, respectively.
- Lastly, we have a getBalance() member function that allows us to retrieve the balance of the account.
- In the main() function, we create two BankAccount objects, account1 and account2, representing two bank accounts for Virat Kohli and Rohit Sharma, respectively.
- We also provide the account number and the account balance for these two accounts.
- Next, we deposit and withdraw money from both accounts by calling deposit() and withdraw() functions on each account separately.
- After that, we call the getBalance() function on both the accounts individually, inside a cout command to access and print the balances.
Read More: Class & Object In C++ | All Related Concepts Explained (With Examples)
The Inheritance OOPs Concept In C++
Inheritance is another fundamental OOPS concept in C++ that allows users to create a new class (called a derived or child class) that inherits properties and behaviours from an existing class (called a base or parent class). Inheritance creates a hierarchical link between classes, facilitating code reuse, extensibility, and the organizing of related classes. It's just like a parent-child relationship in real life.
Let's understand this OOPs concept in C++ with a real-life analogy-
Consider creating a student management system for a university. There are various kinds of students, including postgraduate and undergraduate students. Both types of students have different characteristics and habits, but they also have some common attributes like name, age, and major.
In such a case, say we have a base class that consists of all common characteristics these students have. Then, a derived class (inherited) can consist of all unique characteristics based on student categories like researchTopic, etc.
Syntax:
class BaseClass {
// Base class members
};
class DerivedClass : access_modifier BaseClass {
// Derived class members
};
Here,
- Class: It is a keyword used to define a class.
- BaseClass: It is the name of the base class or parent class
- DerivedClass: It is the name of the class that is derived or inherited from the parent class.
- access_modifier: It is used to represent the inheritance relationship, which could be public, protected, or private.
Let's look at a sample C++ program to better understand this concept.
Code Example:
Output:
Sana has enrolled in Advanced Algorithms
Sana's GPA is 3.8
Sana is presenting research on Machine Learning
Explanation:
In the code above, we define a base class called Student, with three public data members- name (string), age (integer), and major (string).
- The class also contains two public member functions. An enroll_in_course() method that uses the cout command to print a string message indicating the course a student has enrolled in. And a get_gpa() function, which prints a message indicating the student's GPA (hardcoded as 3.8).
- Next, we define a derived class, GraduateStudent, using the public inheritance from the Student class. This means that GraduateStudent inherits all the member variables and member functions of the Student class.
- The derived class with an additional data member researchTopic, which represents the topic of research for a graduate student.
- It also contains two additional member functions, i.e., set_research_topic(), which initiates the research topic for the graduate student. And present_research(), which uses the cout to print a message indicating that the graduate student is presenting research on a specific topic.
- In the main() function, we create an instance of the GraduateStudent class called sana.
- After that, we use the dot operator to initialize the variable data members of the object. We assign values Sana, 25, Computer Science and Machine Learning to the name, age, major, and researchTopic attributes of the object.
- We then use the dot operator and the object sana to call the enroll_in_course() method, indicating that Sana is enrolling in the "Advanced Algorithms" course.
- Similarly, we call the get_gpa() and the present_research() methods to print the values to the console.
Important Note: There are multiple subtypes in inheritance itself, which are defined based on the relationship between and the number of parent and child classes. This includes single inheritance, multi-level inheritance, multiple inheritance, hybrid inheritance, and hierarchical inheritance.
Read More: Inheritance In C++ & Its 5 Types Explained With Multiple Examples
Polymorphism OOPs Concept In C++
As the name suggests, Polymorphism (poly=many morphism=forms) is the ability of a variable or a function to exist in multiple forms. Polymorphism allows the programmer to perform different tasks using the same variable or function. It allows a member function of a class to behave differently based on the object that is used to call it.
Let's understand this OOPs concept in C++ with a real-life analogy-
An example of polymorphism could be human behaviour. Humans typically behave differently with different persons. For example, a person who acts informally with his friends can act formally with his superiors and colleagues. As a result, the person exhibits different behaviour depending on the situation.
There are two types of this OOPs concept in C++ and in programming generally. They are compile-time polymorphism and run-time polymorphism, both of which we will discuss in detail here.
Compile-Time Polymorphism | OOPs Concept In C++
Compilation-time polymorphism is also sometimes referred to as static polymorphism or overloading. In this form of polymorphism, the decision to implement a certain function, behaviour, manipulation operation on objects or variables is made by the compiler at the time of compilation of the C++ code.
Overloading | OOPs Concept In C++
The concept of overloading refers to the practice of giving the same name to multiple objects, such as operators or functions, that behave differently depending on the situation. For example, in function overloading the compiler decides which function to call depending on the function's signature (i.e., the quantity and nature of its parameters) at compile time. The appropriate function is chosen based on the context in which it is called, allowing numerous functions with the same name but with distinct parameter lists to coexist within a class.
There are two types of overloading in C++, which are described in the sections below.
Operator Overloading | OOPs Concept In C++
The way operators behave with primitive data types is already defined. But what about user-defined/non-primitive data types? Well, we can define how common operators (+, -, *, /, etc.) behave or interact with interact user-defined data types and thus alter their behaviour. This ability is known as operator overloading. In reference to classes, you can provide specific actions for these operators when they are applied to objects of your own classes by overloading the operators.
Code Example:
Output:
Vector(2, 3)
Vector(1.5, 2.5)
Vector(3.5, 5.5)
Explanation:
- We define a class Vector to represent two-dimensional vectors with x and y components.
- The class has a constructor of the same name that initializes these double-type elements.
- Next, we define an operator+() function, which takes a constant reference to vectors as an argument. It overloads the addition arithmetic operator by defining how to add two Vector objects together. The function returns a new Vector object with the sum of its components.
- We then define the display() method to print the x and y components of a vector using the cout command.
- In the main() function, we create two Vector objects, v1 and v2 and initialize the component values for x and y.
- We then call the operator+() overloaded function to add these vectors together and store the result in the sum variable.
- Finally, we call the display() function to print the components of v1, v2, and sum.
Read More: Operator Overloading In C++ And Related Concepts (With Examples)
Function Overloading | OOPs Concept In C++
Function overloading, as mentioned before, allows you to define multiple functions with the same name in the same scope but different input parameters, return type, or no of parameters. These help the compiler differentiate between similar functions. This compile-time polymorphism provides us with a way to create functions that perform similar operations. You can use function overloading to make your code more expressive and user-friendly by using the same function name for various behaviours.
Syntax:
return_type function_name(parameters1) {
// Code for the first version of the function
}
return_type function_name(parameters2) {
// Code for the second version of the function
}
Here,
- return_type: It is the data type of the function's return value.
- function_name: It is the name of the function that is being overloaded.
- parameters1: It denotes a list of arguments accepted by the overloaded function.
Let's understand this OOPs concept in C++ with a real-life analogy:
Consider a situation where a student named Amir is interested in displaying his academic background. We can use compile-time polymorphism to provide various information display alternatives using the same method name to satisfy Amir's requirement.
His curiosity is satisfied using two versions of the display method provided by the Student class. The first version presents his basic details like his name, age, and major. The second version, however, takes things a step further by showing his grade point average (GPA), which is a measure of his academic ability, in addition to the same fundamental information.
Code Example:
Output:
Displaying student information:
Name: Amir
Age: 20
Major: Computer ScienceDisplaying student information with GPA:
Name: Amir
Age: 20
Major: Computer Science
GPA: 3.8
Read More: Function Overloading In C++ With Code Examples & Explanation
Run-Time Polymorphism | OOPs Concept In C++
Run-time polymorphism, as the name suggests, is the kind of polymorphism that occurs at run time rather than compile time. Virtual functions and method overriding are used to implement this kind of polymorphism.
- That is, a derived class's ability to provide a particular implementation of a function already specified in its base class is known as method overriding.
- Late binding is made possible via virtual functions, which means that the function call is determined at runtime based on the type of the real object.
- This allows a base class pointer to call the appropriate function in a derived class, even if the pointer is pointing to an object of the child class.
Let's understand this OOPs concept in C++ with a real-life analogy:
Think about a situation where there is a base class called Shape, and classes that are derived from it are Circle and Rectangle.
- Every one of these classes shares a method, say draw(), which prints a message to the effect of the shape being drawn.
- Runtime polymorphism can be seen when the draw() method is called on an instance of a derived class, and the appropriate implementation of the method for that particular derived class is used.
This flexibility enables you to interact with a variety of forms using a standardized interface while taking advantage of the unique characteristics of each shape type.
Function Overriding | OOPs Concept In C++
It is one of the features in object-oriented programming (OOP) wherein a derived class redefines a function of the base class with the same name and signature but a different implementation. Function overriding in C++ facilitates runtime polymorphism by resolving the function call while a program is running. Late binding and dynamic polymorphism are other names for runtime polymorphism.
Syntax:
public class Base{
access_modifier:
// overridden function
return_type function_name(){}
};
}
public class Derived: public Base {
access_modifier:
// overriding function
return_type function_name(){}
};
}
Here,
- Base and Derived refer to the names of the parent and the child class, respectively.
- access_modifier represents the scope of class members, which could be public, protected, or private.
Note that the functions in both classes should have the same signature or function prototype.
Code Example:
Output:
Drawing a shape
Drawing a circle
Drawing a rectangle
Read More: Function Overriding In C++ | Examples, Working Mechanism & More!
Abstraction OOPs Concept In C++
Abstraction is the process of hiding certain data from users and showing only the required information to them. In other words, this OOPs concept in C++ refers to the process of creating simplified models of real-world entities by capturing their essential attributes and behaviours while hiding the complex implementation details. Abstraction makes it easier for the user to use the software as complex code is hidden from them and does not interfere with the interface/experience.
Let's understand this OOPs concept in C++ with a real-life analogy:
Let's consider a scientific calculator (or even a regular calculator) as an example. Whenever we enter data and perform tasks like addition, subtraction, multiplication, percentage, trigonometric functions, etc., the calculator provides us with quick results. All the mechanisms for how the actual calculations are done are hidden from our view as a user. This is one of the simplest real-life examples of abstraction.
Take another example. Say we want to develop software that determines the areas of various geometric objects, such as circles and squares. In this case, we can use abstraction to accomplish this without revealing internal calculations. We start by creating an abstract base class, Shape, with an undefined calculateArea() method. Derived classes like Circle and Square inherit from Shape and provide specific area calculation implementations. By using base class references, instances of different shapes can be created and their areas calculated without directly interacting with their unique logic, promoting code flexibility and maintenance.
This serves as an example of how abstraction streamlines the management of various things under a single umbrella and helps simplify complex systems.
Code Example:
Output:
Circle Area: 78.5397
Square Area: 16
Explanation:
- In the C++ sample code above, we define an abstract class, Shape, which serves as the base class. It contains a pure virtual function calculateArea(), which makes the class abstract. This means that the function is meant to be overridden by derived classes.
- We then create two derived classes, Circle and Square, which inherit from the Shape class. Both classes provide their own implementations for the calculateArea() function.
- The Circle class calculates the area of a circle based on its radius, and the Square class calculates the area of a square based on its side length.
- In the main() function, we create an instance of both the classes, i.e., circle and square. They utilize their respective constructors to set the necessary attributes.
- We then create two pointers for the Shape class (shape1 and shape2) and pass the instances of the derived class as a reference, using the address-of operator (&).
- Essentially, these objects are treated as pointers to the base class Shape, showcasing the concept of abstraction. This allows us to create an array of different shapes without dealing with their specific implementations.
- Next, we call the calculateArea() method on the base class pointers shape1 and shape2, using the arrow/ 'this' pointer, and print the outcomes using the cout command.
- As is evident from the output, appropriate implementations in the derived classes are invoked.
Read More: Data Abstraction In C++ | Types, Use-Cases & More (With Examples)
Encapsulation OOPs Concept In C++
Encapsulation is another fundamental OOPS concept in C++, which entails grouping data (attributes) and the methods (functions) that operate on the data into a single entity, frequently referred to as a class. Encapsulation limits direct access to certain of the object's parts, enabling management and data security.
Let's understand this OOPs concept in C++ with a real-life analogy-
Take a scenario where we need to develop a program for controlling access and guaranteeing data security while handling bank accounts. Here, we create a BankAccount class that has private attributes for the delicate account information, such as account number and amount. The class offers well-constructed methods that act as entry points to interact with the account's data, including deposit, withdraw, and getBalance.
We establish data integrity and security by encapsulating the account data and enforcing actions through methods. The methods provide a trustworthy means to access the account's balance while validating deposits and withdrawals, preventing direct manipulation of properties and other features.
Code Example:
Output:
Deposit of INR 500 successful. New balance: INR 1500
Withdrawal of INR 200 successful. New balance: INR 1300
Insufficient funds or invalid amount.
Current balance: INR 1300
Explanation:
In the C++ example program-
- We define a BankAccount class that encapsulates the attributes of an account, like the account number, balance, and methods to interact with the account.
- There are two private data members, i.e., accountNumber and balance.
- We define a member function deposit() to add a positive amount to the account balance and print the updated balance when called.
- Another member function, withdraw(), takes an amount as an argument and checks if the amount is positive and less than the current balance using the logical AND operator and relational equality operator.
- If the conditions are satisfied, it subtracts the amount from the balance data member and prints the updated balance to the console.
- Or else, it prints a string message stating that the amount is invalid or the balance is insufficient when called.
- Lastly, we have the getBalance() method, which returns the current balance.
- In the main() function, we create an object of the BankAccount class called account, with an account number of "12345" and an initial balance of 1000.0.
- We then use the dot operator to call the deposit() method on the account object, with an amount of 500.0, which increases the balance to 1500.0.
- Next, we call the withdraw() method twice. First, with an amount of 200.0, which decreases the balance to 1300.0. And second, with an amount of 1500.0, which is an invalid withdrawal and prints an error message.
- Finally, we call the getBalance() method and print the current balance of 1300.0 using the cout command.
Read More: Encapsulation In C++ | Getter/ Setter Methods & More (+Examples)
Other Features Of OOPs In C++
The five concepts mentioned above form the core of the OOPs concepts in C++. However, there are a few other features of OOPs/ concepts in OOPs that are worth mentioning. They are discussed in this section.
Exception Handling | OOPs Concept In C++
Exception handling is a programming concept that enables you to handle and react to unexpected or exceptional situations that could arise while a program is being executed. These circumstances, which are sometimes referred to as exceptions, may include mistakes, issues, or unexpected events that block the normal process of code execution.
The purpose of exception handling is to provide a structured method of managing errors gracefully while preventing sudden program termination. With exception handling, you can detect, deal with, and maybe recover from unusual circumstances without having the program crash.
Syntax:
try {
// Code that might throw an exception
// ...
if (/* Some condition that indicates an error */) {
throw exception;}
} catch () {
// Code to handle exception
// ...
}
Here,
- try: It is a keyword that allows you to define a block of code to be tested for errors while it is being executed.
- throw: It is a keyword that throws an exception when a problem is detected,
- catch: It allows you to define a block of code to be executed if an error occurs in the try block.
- exception: It specifies the type of the error generated while executing the try block
Let's understand this related OOPs concept in C++ with a real-life analogy
Consider an online payment processing system. In this scenario, exception handling is essential to properly handle circumstances like unsuccessful transactions caused by network issues, insufficient cash, or incorrect card information. The system can deliver user-friendly error notifications, undo incomplete transactions, and guarantee the dependability and integrity of financial activities by implementing exception handling. This improves user experience and guards against any financial losses brought on by unanticipated mistakes made during payment processing.
Code Example:
Output:
Exception caught: Division by zero
Read More: C++ Exception Handling | Use Try, Catch, & Throw (+Examples)
Constructors in OOPS in C++ | OOPs Concept In C++
Constructors in C++ are special member functions that are called automatically when an object belonging to a class is created. The constructors are responsible for the initialization of the object's data members and the establishment of its initial state. They make sure that an object is created with valid and consistent values, establishing the foundation for the object's functionality and behaviour.
Constructors are particularly helpful for allocating resources, setting initial values, and setting up the object for use immediately after creation. They have the same name as the class name and don't have the return type, not even void. Here is the standard syntax of the constructor in C++.
Syntax:
class ClassName {
Access_specifier:
ClassName() {
}
};
Here,
- class: It is the keyword used to define the class
- ClassName: It is the name of the class in which the constructor is defined
- Access_specifier: It is a data visibility controller which could be public, private, protected
- ClassName(): It is a constructor (It has the same name as the class name)
Let's understand by a real-life analogy
Consider that we are developing a program to handle student data. In this case, we've created a class called Student with the characteristics of name, age, and major. We've included a default constructor to simplify object creation.
The default constructor automatically activates when we create a Student object without specifying any special values. The attributes of the object are initialized with predetermined default values in this constructor, such as Unknown for the name, 0 for the age, and Undeclared for the major.
Code Example:
Output:
Student 1 details:
Name: Unknown
Age: 0
Major: Undeclared
Explanation:
In the example, we create a class, Student, with three attributes- name, age, and major. We also define a default constructor, Student(), inside the class, which initializes the attributes to default values ("Unknown" for name, 0 for age, and "Undeclared" for major). Then, we create an object student1 of the Student class using this default constructor inside the main() function. Since no arguments are provided, the default constructor is automatically called.
Read More: Constructor In C++ | Types, Benefits, Uses & More (With Examples)
There are multiple types of constructors, and they are classified based on their basic nature, parameters, and behaviour. This includes:
Parameterized Constructor: In C++, the parameterized constructor is a particular kind of constructor that accepts one or more parameters as arguments when creating an object. It enables you to supply unique values when initializing an object's data members. It is especially helpful when you want to create objects with specific beginning states based on the supplied inputs.
Syntax:
class ClassName {
Access_specifier:
ClassName(parameter_type parameter1, parameter_type parameter2, ...){
}
};
Here,
- The class keyword indicates that we are defining a class by the name ClassName.
- Access_specifier is the data visibility controller which determines who can access the data.
- The ClassName() is the parameterized constructor which takes a parameter list consisting of paramater1, parameter 2, and so on.
- parameter _type is the data type of the respective parameter.
Let's understand by a real-life analogy:
Let's consider a scenario where we need to model rectangles in a program. To achieve this, we define a Rectangle class with attributes width and height. In this scenario, we utilize the parameterized constructor to create a Rectangle object named rect with specific width and height values. The constructor initializes these values when the object is created.
Copy Constructor: It is a special constructor in C++ that makes a copy of an existing object while creating a new one. It is utilized whenever an object is passed as a value to a function, returned as a value from a function, or when an object is given the value of another object belonging to the same class. The copy constructor in C++ makes sure that the new object's data members are set to the same values as those of the source object.
Syntax:
class ClassName {
Access_specifier:
ClassName( ClassName &source){
// Copy data members from the source object
}
};
Here, the syntax is the same as that of the constructor, with two differences. First, the ClassName() here refers to the copy constructor. Second, the ClassName &source is a parameter of the copy constructor that accepts objects of the same class.
Benefits Of OOP In C++ Over Procedural-Oriented Programming
Procedural programming languages encompass techniques that revolve around the concept of procedures or functions. Here, the whole program is divided into smaller single functions or modules that perform specific tasks. On the other hand, OOP revolves around creating models that mimic real-world entities through the use of objects and the encapsulation of data and behaviour.
Object-oriented programming offers several advantages over procedure-oriented programming. They are as follows:
- Modularity and Reusability: The OOPS Concept in C++ allows you to create classes and objects, promoting modularity and reusability. This enables you to build components that can be used across different parts of your program, reducing redundancy and making maintenance easier.
- Encapsulation: This feature of OOP in C++ helps hide implementation details and safeguards data from unwanted access by encapsulating it in a class containing data and functions. This improves data security and stops unauthorized changes.
- Abstraction: It is an OOP concept or technique where you focus on essential features and ignore unnecessary details. This simplifies program design, making it easier to comprehend and manage complex systems.
- Inheritance: This OOPs concept in C++ facilitates the creation of new classes that inherit attributes and behaviors from existing classes. This promotes code reuse and allows you to create specialized classes that build upon the features of a base class.
- Polymorphism: This feature of OOPs in C++ enables the use of a single interface to represent different data types or objects. This promotes code flexibility and simplifies code maintenance by allowing you to extend or modify behaviour without altering existing code.
- Code Maintenance: The modular and organized structure provided by many features of OOPs in C++ simplifies code maintenance. For example, changes made to a class are localized, reducing the risk of unintended side effects in other parts of the program.
- Collaborative Development: The class OOPs concept in C++ enables multiple programmers to work on several classes simultaneously. This promotes collaborative development, which makes large-scale software projects more manageable and increases productivity.
- Real-World Modeling: The entities and connections in OOP are very similar to those in reality. This improves the overall understanding of the function and behaviour of the program by making it simpler to translate real-world circumstances into code.
- Error Handling: The features of OOP in C++ promote better error handling through mechanisms like exceptions, making it easier to identify and manage errors during runtime
- Scalability: Both small and large-scale initiatives can benefit from the OOPs concept in C++ programming. For example, as a project scales in size and becomes more complex, characteristics of OOP, like encapsulation, inheritance, and modularity, make it simpler to scale and manage complexity.
Disadvantages Of OOPS Concept In C++
Here are some of the disadvantages of the OOPS concept in C++ that limit its usage-
- Overhead: The necessity to handle objects, inheritance hierarchies, and dynamic dispatching in OOP might result in significant overhead. Compared to more procedural approaches, these features of OOP in C++ programs may result in slightly slower program execution.
- Complexity: Applying multiple OOPs concepts in C++ programs can result in complicated code architectures, particularly in large projects with intricate class interactions. The complexity of the code may make it more challenging to comprehend and update.
- Learning Curve: Compared to more procedural programming, OOPS concepts in C++, like classes, objects, inheritance, and polymorphism, may have a longer learning period for newcomers.
- Run-time Overhead: For some features of OOP in C++ where the proper technique must be determined at runtime, for example, dynamic binding and virtual functions, there may be run-time overhead.
- Efficiency: When dealing with small and numerous objects, OOP may not always be as memory-efficient as procedural programming. Storage of more object-related data can result in memory overhead that can cause problems.
- Performance: While modern compilers do a good job of optimizing OOP code, there may be some situations in which direct procedural code is more performance-efficient, particularly in some low-level programming contexts.
- Encapsulation trade-offs: Although the encapsulation OOPs concept in C++ protects data, it can occasionally result in an excessive number of getter and setter methods. This could result in more complex code and poorer performance.
- Design Difficulty: Complex class hierarchies due to inheritance OOPs concept in C++ can be difficult to design correctly. And bad design decisions might cause architectural issues later in the development process.
Why Is C++ A Partial OOP Language?
The fundamental elements that make up an object-oriented programming language are inheritance, polymorphism, and encapsulation. Any programming language that fully supports these features is considered to be an object-oriented programming language, but a language that partially supports all three features is considered to be partial object-oriented programming.
Here are some of the OOP concepts that are supported by C++:
- Classes: Classes are the basic building blocks of OOP. They are used to represent real-world objects and their properties.
- Objects: Objects are instances of classes. They have the properties and behaviours defined by their class.
- Inheritance: This OOPs concept in C++ refers to the ability of one class to inherit the properties and behaviors of another class.
- Polymorphism: This feature of OOP in C++ represents the ability of objects to take on different forms. It is achieved through overloading and overriding.
- Encapsulation: This OOPs concept entails hiding data and implementation details from the user.
While C++ programming language supports some of the most prominent OOPs concepts, there are some concepts that are not supported by C++. These include:
- Garbage collection: Garbage collection is the automatic management of memory. C++ does not have garbage collection, so the programmer is responsible for managing memory manually.
- Multiple Dispatch: C++ primarily uses single dispatch, which means that the method called is determined by the type of object it is called on (static dispatch). Multiple dispatch, where the method is chosen based on the types of multiple objects involved, is not directly supported.
- Final classes: Final classes cannot be subclassed in C++ since it does not have final classes.
- It is possible to write C++ code without using classes: This means that you can create programs in C++ that do not use the OOP concepts of encapsulation, inheritance, and polymorphism.
- C++ has a global namespace: This means that all variables and functions are accessible from anywhere in the program, even if they are declared inside a class. This can make it difficult to maintain the privacy of data and the modularity of code.
- C++ has a manual memory management system: This means that the programmer is responsible for allocating and freeing memory. This can be a source of errors and can make it difficult to write reliable code.
Because of these limitations, C++ is considered a partial OOP language. However, it is still a powerful language that can be used to create complex and sophisticated programs. Despite these limitations, C++ is a versatile language that is used to create a wide variety of software, including operating systems, compilers, and games.
Code Example:
Output:
My name is Ashish Jain and I am 25 years old.
Explanation:
- We begin by including the <iostream> header file and start with the int main() function.
- Then, we declare and initialize an integer variable age with the value of 25. The int keyword specifies that the variable age is an integer.
- Next, we declare a string variable, name, using std::string and initialize it with the value Ashish Jain. The std::string keyword specifies that the variable name is a string.
- Then, we use the std::cout statements to print the name and age variable along with a phrase.
- Finally, the return 0 statement indicates that the program has terminated successfully. The return keyword tells the compiler to return the value 0 from the function.
This code does not use any classes. It simply declares two variables, age and name, and then prints their values to the console. This is perfectly valid C++ code even though it does not take advantage of the OOP concepts in C++.
Conclusion
In conclusion, object-oriented programming (OOP) is a foundational paradigm in C++ that empowers developers to create well-organized, modular, and maintainable code. Through the use of OOPs concepts in C++, such as classes and objects, encapsulation, inheritance, polymorphism, and abstraction, programmers can design software systems that are both efficient and adaptable.
By mastering these OOPs concepts in C++, developers can create code that is not only more organized and readable but also easier to maintain and extend. This approach enhances collaboration, reduces bugs, and promotes the development of robust and scalable software solutions. As such, OOP remains a cornerstone of modern C++ programming, ensuring that codebases remain agile and adaptable to evolving requirements and challenges.
Also read- 51 C++ Interview Questions For Freshers & Experienced (With Answers)
Frequently Asked Questions
Q. What is the OOPS concept in C++?
Object-oriented programming (OOP) is a programming paradigm that emphasizes using classes and objects to structure code and model real-world entities and their relationships. There is a set of OOPs concept in C++ that help in designing, organizing, and managing code. Some of the key features of OOP in C++ are:
- Classes and Objects: Classes are blueprints that define attributes and methods, while objects are instances of classes. They encapsulate data and behaviour.
- Inheritance: This OOPs concept in C++ allows one class (derived or subclass) to inherit attributes and behaviors from another class (base or superclass). It promotes code reuse and hierarchy formation. Multilevel inheritance and hierarchical inheritance are some of the examples.
- Polymorphism: This OOPs concept in C++ enables objects of different classes to be treated uniformly through a common interface. It involves overloading and method overriding.
- Encapsulation: This OOPs concept in C++ entails bundling data and methods within a class and hiding implementation details. Access to data is controlled through access specifiers.
- Abstraction: This OOPs concept in C++ focuses on essential features while ignoring unnecessary details. Classes provide an abstract internal representation of real-world entities.
Q. Why is the use of abstraction?
Abstraction is the practice of hiding complex details from the end user and only showing the most essential information. Here are some of the uses of abstraction-
- Simplification: The feature of OOP in C++ reduces complexity by breaking down a system into manageable components and interactions. It allows developers to work with high-level concepts without getting lost in implementation specifics.
- Security and Data Hiding: The abstraction OOPs concept in C++ facilitates data encapsulation and access control, enhancing data security and preventing unauthorized access to sensitive information.
- Clarity and Readability: By highlighting the most important information and hiding complex details, the abstraction OOPs concept in C++ helps write code that is simpler to understand. This makes the codebase's overall readability better.
- Maintenance and Updates: Abstracting complex details isolates them from the rest of the system. When changes or updates are needed, modifications can be made within the abstraction without affecting the external interface, minimizing the risk of introducing errors.
Q. What is the real-life example of the class OOPs concept in C++?
One real-world example of a class in object-oriented programming (OOP) is the concept of a bank account. Here, we can say that the Bank Account class defines attributes (like account number and amount) and methods (like deposit and withdrawal), just as in OOP.
These aspects of the object would stand in for individual bank accounts by encapsulating data and operations in a systematic way. This abstraction simulates the interactions of real-world entities, which makes it simpler to store and manipulate financial data in a consistent and structured manner.
Q. What are some major object-oriented programming languages?
The powerful programming languages that follow the object-oriented programming paradigm or design are called object-oriented programming languages. Following are some such languages:
- Java
- Javascript
- Python
- PHP
- C#
- Ruby
- CPP
Q. In C++, is a class object stored in a heap or stack?
The memory allocated to the object depends upon how the object is created. Objects in C++ can be allocated either in stack or heap memory, depending on creation and scope. Let’s elaborate a little more on this.
Stack: A class object is kept in the stack memory when it is created as a local variable inside a function or a block. The program automatically allocates and deallocates the object's memory when it enters and leaves the defined scope of the object.
Example:
void someFunction() {
MyClass obj; // Object 'obj' is stored in the stack
}
Here, Object 'obj' is automatically deallocated when the function exits
Heap: A class object created using dynamic memory allocation (with the new operator) is kept in the heap memory. To prevent memory leaks, the object's memory must be manually deallocated using delete.
Example:
void someFunction() {
MyClass* objPtr = new MyClass(); // Object is created in the heap
delete objPtr;
}
Here, Object ‘objPtr’ must be manually deallocated using the delete keyword.
Q. What are different types of polymorphism?
There are two primary types of the polymorphism OOPs concept in C++, which are further divided into sub-types or use cases. They are-
Compile time polymorphism: This type of polymorphism is also known as early binding. Usually, function overloading and operator overloading are used to achieve compile time polymorphism.
- Function overloading enables the definition of numerous special functions in a class with the same name but distinct argument lists.
- The correct function is determined at compile-time based on the arguments supplied.
- Using operator overloading, you can also specify how operators interact with user-defined data types. This is decided at compile-time based on the kinds of operands and the operators employed.
Runtime polymorphism: Runtime polymorphism is when the choice of which function is to be called is based on the object's actual type, determined at run time. Examples of polymorphism at runtime include method overriding and virtual function. This is also referred to as dynamic polymorphism, and it involves the use of virtual functions and different types of inheritance to achieve flexible and adaptable behaviour in object-oriented programming languages.
Q. What is meant by exception handling?
Exception handling is a programming method used to handle and react to unexpected or unusual situations that may arise while a program is being executed. These unusual occurrences are frequently referred to as exceptions. Instead of allowing mistakes, anomalies, and other uncommon circumstances to cause the program to crash or deliver unpredictable consequences, exception handling offers a structured technique to handle them in a controlled manner.
This compiles our discussion on OOPs concept in C++. Here are a few more C++ topics you should explore:
- Friend Function In C++ | Class, Types, Uses & More (+Examples)
- Static Member Function In C++ Explained With Proper Examples
- Inline Function In C++ | Declare, Working, Examples & More!
- C++ Type Conversion & Type Casting Demystified (With Examples)
- Destructor In C++ | Understanding The Key To Cleanups (+ Examples)
- Constructor Overloading In C++ Explained With Real Examples