Author: saqibkhan

  • Write a Program to Check Whether a Character is a Vowel or Consonant

    C++// C++ Program to print whether a character is vowel or not #include <cctype> #include <iostream> using namespace std; int main() { char ch = 'e'; if (isalpha(ch)) { if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') { cout << ch << " is a vowel." << endl; } else { cout << ch << " is a consonant." << endl; } } else { cout << ch << " is not an alphabet." << endl; } return 0; }

    Output

    e is a vowel.
  • Data Abstraction in C++

    Data abstraction refers to providing only essential information to the outside world and hiding their background details, i.e., to represent the needed information in program without presenting the details.

    Data abstraction is a programming (and design) technique that relies on the separation of interface and implementation.

    Let’s take one real life example of a TV, which you can turn on and off, change the channel, adjust the volume, and add external components such as speakers, VCRs, and DVD players, BUT you do not know its internal details, that is, you do not know how it receives signals over the air or through a cable, how it translates them, and finally displays them on the screen.

    Thus, we can say a television clearly separates its internal implementation from its external interface and you can play with its interfaces like the power button, channel changer, and volume control without having any knowledge of its internals.

    In C++, classes provides great level of data abstraction. They provide sufficient public methods to the outside world to play with the functionality of the object and to manipulate object data, i.e., state without actually knowing how class has been implemented internally.

    For example, your program can make a call to the sort() function without knowing what algorithm the function actually uses to sort the given values. In fact, the underlying implementation of the sorting functionality could change between releases of the library, and as long as the interface stays the same, your function call will still work.

    In C++, we use classes to define our own abstract data types (ADT). You can use the cout object of class ostream to stream data to standard output like this −

    #include <iostream>
    using namespace std;
    
    int main() {
       cout << "Hello C++" <<endl;
       return 0;
    }

    Here, you don’t need to understand how cout displays the text on the user’s screen. You need to only know the public interface and the underlying implementation of ‘cout’ is free to change.

    Access Labels Enforce Abstraction

    In C++, we use access labels to define the abstract interface to the class. A class may contain zero or more access labels −

    • Members defined with a public label are accessible to all parts of the program. The data-abstraction view of a type is defined by its public members.
    • Members defined with a private label are not accessible to code that uses the class. The private sections hide the implementation from code that uses the type.

    There are no restrictions on how often an access label may appear. Each access label specifies the access level of the succeeding member definitions. The specified access level remains in effect until the next access label is encountered or the closing right brace of the class body is seen.

    Benefits of Data Abstraction

    Data abstraction provides two important advantages −

    • Class internals are protected from inadvertent user-level errors, which might corrupt the state of the object.
    • The class implementation may evolve over time in response to changing requirements or bug reports without requiring change in user-level code.

    By defining data members only in the private section of the class, the class author is free to make changes in the data. If the implementation changes, only the class code needs to be examined to see what affect the change may have. If data is public, then any function that directly access the data members of the old representation might be broken.

    Data Abstraction Example

    Any C++ program where you implement a class with public and private members is an example of data abstraction. Consider the following example −

    #include <iostream>
    using namespace std;
    
    class Adder {
       public:
    
      // constructor
      Adder(int i = 0) {
         total = i;
      }
      
      // interface to outside world
      void addNum(int number) {
         total += number;
      }
      
      // interface to outside world
      int getTotal() {
         return total;
      };
      
    private:
      // hidden data from outside world
      int total;
    }; int main() { Adder a; a.addNum(10); a.addNum(20); a.addNum(30); cout << "Total " << a.getTotal() <<endl; return 0; }

    When the above code is compiled and executed, it produces the following result −

    Total 60
    

    Above class adds numbers together, and returns the sum. The public members – addNum and getTotal are the interfaces to the outside world and a user needs to know them to use the class. The private member total is something that the user doesn’t need to know about, but is needed for the class to operate properly.

    Designing Strategy

    Abstraction separates code into interface and implementation. So while designing your component, you must keep interface independent of the implementation so that if you change underlying implementation then interface would remain intact.

    In this case whatever programs are using these interfaces, they would not be impacted and would just need a recompilation with the latest implementation.

  • Write a Program to Find the ASCII Value of a Character

    C++// C++ Program to find ASCII value of a character #include <iostream> using namespace std; int main() { char ch; ch = 'A'; cout << "The ASCII value of " << ch << " is " << int(ch) << endl; return 0; }

    Output

    The ASCII value of A is 65
  •  C++ Program To Check Whether Number is Even Or Odd

    C++// C++ program to check // for even or odd #include <iostream> using namespace std; // Returns true if n is // even, else odd bool isEven(int n) { return (n % 2 == 0); } // Driver code int main() { int n = 247; if (isEven(n) == true) { cout << "Even" << endl; } else { cout << "Odd"; } return 0; }

    Output

    Odd
  • Polymorphism 

    The word polymorphism means having many forms. Typically, polymorphism occurs when there is a hierarchy of classes and they are related by inheritance.

    C++ polymorphism means that a call to a member function will cause a different function to be executed depending on the type of object that invokes the function.

    Consider the following example where a base class has been derived by other two classes −

    Open Compiler

    #include <iostream> usingnamespace std;classShape{protected:int width, height;public:Shape(int a =0,int b =0){
    
         width = a;
         height = b;}intarea(){
         cout &lt;&lt;"Parent class area :"&lt;&lt; width * height &lt;&lt; endl;return width * height;}};classRectangle:public Shape{public:Rectangle(int a =0,int b =0):Shape(a, b){}intarea(){ 
         cout &lt;&lt;"Rectangle class area :"&lt;&lt; width * height &lt;&lt; endl;return(width * height);}};classTriangle:public Shape{public:Triangle(int a =0,int b =0):Shape(a, b){}intarea(){ 
         cout &lt;&lt;"Triangle class area :"&lt;&lt;(width * height)/2&lt;&lt; endl;return(width * height /2);}};// Main function for the programintmain(){
    Shape *shape; Rectangle rec(10,7); Triangle tri(10,5);// store the address of Rectangle shape =&rec;// call rectangle area. shape->area();// store the address of Triangle shape =&tri;// call triangle area. shape->area();return0;}

    When the above code is compiled and executed, it produces the following result −

    Parent class area :70
    Parent class area :50
    

    The reason for the incorrect output is that the call of the function area() is being set once by the compiler as the version defined in the base class. This is called static resolution of the function call, or static linkage – the function call is fixed before the program is executed. This is also sometimes called early binding because the area() function is set during the compilation of the program.

    But now, let’s make a slight modification in our program and precede the declaration of area() in the Shape class with the keyword virtual so that it looks like this −

    Open Compiler

    #include <iostream>usingnamespace std;classShape{protected:int width, height;public:Shape(int a =0,int b =0){
    
         width = a;
         height = b;}virtualintarea(){
         cout &lt;&lt;"Parent class area :"&lt;&lt; width * height &lt;&lt; endl;return width * height;}};classRectangle:public Shape{public:Rectangle(int a =0,int b =0):Shape(a, b){}intarea(){
         cout &lt;&lt;"Rectangle class area :"&lt;&lt; width * height &lt;&lt; endl;return(width * height);}};classTriangle:public Shape{public:Triangle(int a =0,int b =0):Shape(a, b){}intarea(){
         cout &lt;&lt;"Triangle class area :"&lt;&lt;(width * height)/2&lt;&lt; endl;return(width * height /2);}};// Main function for the programintmain(){
    Shape *shape; Rectangle rec(10,7); Triangle tri(10,5);// store the address of Rectangle shape =&rec;// call rectangle area. shape->area();// store the address of Triangle shape =&tri;// call triangle area. shape->area();return0;}

    After this slight modification, when the previous example code is compiled and executed, it produces the following result −

    Rectangle class area :70
    Triangle class area :25
    

    This time, the compiler looks at the contents of the pointer instead of it’s type. Hence, since addresses of objects of tri and rec classes are stored in *shape the respective area() function is called.

    As you can see, each of the child classes has a separate implementation for the function area(). This is how polymorphism is generally used. You have different classes with a function of the same name, and even the same parameters, but with different implementations.

    Virtual Function

    virtual function is a function in a base class that is declared using the keyword virtual. Defining in a base class a virtual function, with another version in a derived class, signals to the compiler that we don’t want static linkage for this function.

    What we do want is the selection of the function to be called at any given point in the program to be based on the kind of object for which it is called. This sort of operation is referred to as dynamic linkage, or late binding.

    Pure Virtual Functions

    It is possible that you want to include a virtual function in a base class so that it may be redefined in a derived class to suit the objects of that class, but that there is no meaningful definition you could give for the function in the base class.

    We can change the virtual function area() in the base class to the following −

    class Shape {
       protected:
    
      int width, height;
    public:
      Shape(int a = 0, int b = 0) {
         width = a;
         height = b;
      }
      
      // pure virtual function
      virtual int area() = 0;
    };

    The = 0 tells the compiler that the function has no body and above virtual function will be called pure virtual function.

  • Overloading 

    C++ allows you to specify more than one definition for a function name or an operator in the same scope, which is called function overloading and operator overloading respectively.

    An overloaded declaration is a declaration that is declared with the same name as a previously declared declaration in the same scope, except that both declarations have different arguments and obviously different definition (implementation).

    When you call an overloaded function or operator, the compiler determines the most appropriate definition to use, by comparing the argument types you have used to call the function or operator with the parameter types specified in the definitions. The process of selecting the most appropriate overloaded function or operator is called overload resolution.

    Function Overloading in C++

    You can have multiple definitions for the same function name in the same scope. The definition of the function must differ from each other by the types and/or the number of arguments in the argument list. You cannot overload function declarations that differ only by return type.

    Following is the example where same function print() is being used to print different data types −

    Open Compiler

    #include <iostream>usingnamespace std;classprintData{public:voidprint(int i){
    
        cout &lt;&lt;"Printing int: "&lt;&lt; i &lt;&lt; endl;}voidprint(double  f){
        cout &lt;&lt;"Printing float: "&lt;&lt; f &lt;&lt; endl;}voidprint(char* c){
        cout &lt;&lt;"Printing character: "&lt;&lt; c &lt;&lt; endl;}};intmain(void){
    printData pd;// Call print to print integer pd.print(5);// Call print to print float pd.print(500.263);// Call print to print character pd.print("Hello C++");return0;}

    When the above code is compiled and executed, it produces the following result −

    Printing int: 5
    Printing float: 500.263
    Printing character: Hello C++
    

    Operators Overloading in C++

    You can redefine or overload most of the built-in operators available in C++. Thus, a programmer can use operators with user-defined types as well.

    Overloaded operators are functions with special names: the keyword “operator” followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.

    Box operator+(const Box&);

    declares the addition operator that can be used to add two Box objects and returns final Box object. Most overloaded operators may be defined as ordinary non-member functions or as class member functions. In case we define above function as non-member function of a class then we would have to pass two arguments for each operand as follows −

    Box operator+(const Box&,const Box&);

    Following is the example to show the concept of operator over loading using a member function. Here an object is passed as an argument whose properties will be accessed using this object, the object which will call this operator can be accessed using this operator as explained below −

    Open Compiler

    #include <iostream>usingnamespace std;classBox{public:doublegetVolume(void){return length * breadth * height;}voidsetLength(double len ){
    
         length = len;}voidsetBreadth(double bre ){
         breadth = bre;}voidsetHeight(double hei ){
         height = hei;}// Overload + operator to add two Box objects.
      Box operator+(const Box&amp; b){
         Box box;
         box.length =this-&gt;length + b.length;
         box.breadth =this-&gt;breadth + b.breadth;
         box.height =this-&gt;height + b.height;return box;}private:double length;// Length of a boxdouble breadth;// Breadth of a boxdouble height;// Height of a box};// Main function for the programintmain(){
    Box Box1;// Declare Box1 of type Box Box Box2;// Declare Box2 of type Box Box Box3;// Declare Box3 of type Boxdouble volume =0.0;// Store the volume of a box here// box 1 specification Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0);// box 2 specification Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0);// volume of box 1 volume = Box1.getVolume(); cout <<"Volume of Box1 : "<< volume <<endl;// volume of box 2 volume = Box2.getVolume(); cout <<"Volume of Box2 : "<< volume <<endl;// Add two object as follows: Box3 = Box1 + Box2;// volume of box 3 volume = Box3.getVolume(); cout <<"Volume of Box3 : "<< volume <<endl;return0;}

    When the above code is compiled and executed, it produces the following result −

    Volume of Box1 : 210
    Volume of Box2 : 1560
    Volume of Box3 : 5400
    
    
    

    Overloadable/Non-overloadableOperators

    Following is the list of operators which can be overloaded −

    +*/%^
    &|~!,=
    <><=>=++
    <<>>==!=&&||
    +=-=/=%=^=&=
    |=*=<<=>>=[]()
    ->->*newnew []deletedelete []

    Following is the list of operators, which can not be overloaded −

    ::.*.?:

    Operator Overloading Examples

    Here are various operator overloading examples to help you in understanding the concept.

    Sr.NoOperators & Example
    1Unary Operators Overloading
    2Binary Operators Overloading
    3Relational Operators Overloading
    4Input/Output Operators Overloading
    5++ and — Operators Overloading
    6Assignment Operators Overloading
    7Function call () Operator Overloading
    8Subscripting [] Operator Overloading
    9Class Member Access Operator -> Overloading
  • Inheritance

    One of the most important concepts in object-oriented programming is that of inheritance. Inheritance allows us to define a class in terms of another class, which makes it easier to create and maintain an application. This also provides an opportunity to reuse the code functionality and fast implementation time.

    When creating a class, instead of writing completely new data members and member functions, the programmer can designate that the new class should inherit the members of an existing class. This existing class is called the base class, and the new class is referred to as the derived class.

    The idea of inheritance implements the is a relationship. For example, mammal IS-A animal, dog IS-A mammal hence dog IS-A animal as well and so on.

    Base and Derived Classes

    A class can be derived from more than one classes, which means it can inherit data and functions from multiple base classes. To define a derived class, we use a class derivation list to specify the base class(es). A class derivation list names one or more base classes and has the form −

    class derived-class: access-specifier base-class
    

    Where access-specifier is one of public, protected, or private, and base-class is the name of a previously defined class. If the access-specifier is not used, then it is private by default.

    Consider a base class Shape and its derived class Rectangle as follows −

    #include <iostream>
     
    using namespace std;
    
    // Base class
    class Shape {
       public:
    
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }
      
    protected:
      int width;
      int height;
    }; // Derived class class Rectangle: public Shape { public:
      int getArea() { 
         return (width * height); 
      }
    }; int main(void) { Rectangle Rect; Rect.setWidth(5); Rect.setHeight(7); // Print the area of the object. cout << "Total area: " << Rect.getArea() << endl; return 0; }

    When the above code is compiled and executed, it produces the following result −

    Total area: 35
    

    Access Control and Inheritance

    A derived class can access all the non-private members of its base class. Thus base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class.

    We can summarize the different access types according to – who can access them in the following way −

    Accesspublicprotectedprivate
    Same classyesyesyes
    Derived classesyesyesno
    Outside classesyesnono

    A derived class inherits all base class methods with the following exceptions −

    • Constructors, destructors and copy constructors of the base class.
    • Overloaded operators of the base class.
    • The friend functions of the base class.

    Type of Inheritance

    When deriving a class from a base class, the base class may be inherited through public, protected or private inheritance. The type of inheritance is specified by the access-specifier as explained above.

    We hardly use protected or private inheritance, but public inheritance is commonly used. While using different type of inheritance, following rules are applied −

    • Public Inheritance − When deriving a class from a public base class, public members of the base class become public members of the derived class and protected members of the base class become protected members of the derived class. A base class’s private members are never accessible directly from a derived class, but can be accessed through calls to the public and protected members of the base class.
    • Protected Inheritance − When deriving from a protected base class, public and protected members of the base class become protected members of the derived class.
    • Private Inheritance − When deriving from a private base class, public and protected members of the base class become private members of the derived class.

    Multiple Inheritance

    A C++ class can inherit members from more than one class and here is the extended syntax −

    class derived-class: access baseA, access baseB....
    

    Where access is one of public, protected, or private and would be given for every base class and they will be separated by comma as shown above. Let us try the following example −

    #include <iostream>
     
    using namespace std;
    
    // Base class Shape
    class Shape {
       public:
    
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }
      
    protected:
      int width;
      int height;
    }; // Base class PaintCost class PaintCost { public:
      int getCost(int area) {
         return area * 70;
      }
    }; // Derived class class Rectangle: public Shape, public PaintCost { public:
      int getArea() {
         return (width * height); 
      }
    }; int main(void) { Rectangle Rect; int area; Rect.setWidth(5); Rect.setHeight(7); area = Rect.getArea(); // Print the area of the object. cout << "Total area: " << Rect.getArea() << endl; // Print the total cost of painting cout << "Total paint cost: $" << Rect.getCost(area) << endl; return 0; }

    When the above code is compiled and executed, it produces the following result −

    Total area: 35
    Total paint cost: $2450
    
  • Classes and Objects

    The main purpose of C++ programming is to add object orientation to the C programming language and classes are the central feature of C++ that supports object-oriented programming and are often called user-defined types.

    A class is used to specify the form of an object and it combines data representation and methods for manipulating that data into one neat package. The data and functions within a class are called members of the class.

    C++ Class Definitions

    When you define a class, you define a blueprint for a data type. This doesn’t actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object.

    A class definition starts with the keyword class followed by the class name; and the class body, enclosed by a pair of curly braces. A class definition must be followed either by a semicolon or a list of declarations. For example, we defined the Box data type using the keyword class as follows −

    class Box {
       public:
    
      double length;   // Length of a box
      double breadth;  // Breadth of a box
      double height;   // Height of a box
    };

    The keyword public determines the access attributes of the members of the class that follows it. A public member can be accessed from outside the class anywhere within the scope of the class object. You can also specify the members of a class as private or protected which we will discuss in a sub-section.

    Define C++ Objects

    A class provides the blueprints for objects, so basically an object is created from a class. We declare objects of a class with exactly the same sort of declaration that we declare variables of basic types. Following statements declare two objects of class Box −

    Box Box1;          // Declare Box1 of type Box
    Box Box2;          // Declare Box2 of type Box
    

    Both of the objects Box1 and Box2 will have their own copy of data members.

    Accessing the Data Members

    The public data members of objects of a class can be accessed using the direct member access operator (.). Let us try the following example to make the things clear −

    #include <iostream>
    
    using namespace std;
    
    class Box {
       public:
    
      double length;   // Length of a box
      double breadth;  // Breadth of a box
      double height;   // Height of a box
    }; int main() { Box Box1; // Declare Box1 of type Box Box Box2; // Declare Box2 of type Box double volume = 0.0; // Store the volume of a box here // box 1 specification Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0; // box 2 specification Box2.height = 10.0; Box2.length = 12.0; Box2.breadth = 13.0; // volume of box 1 volume = Box1.height * Box1.length * Box1.breadth; cout << "Volume of Box1 : " << volume <<endl; // volume of box 2 volume = Box2.height * Box2.length * Box2.breadth; cout << "Volume of Box2 : " << volume <<endl; return 0; }

    When the above code is compiled and executed, it produces the following result −

    Volume of Box1 : 210
    Volume of Box2 : 1560
    

    It is important to note that private and protected members can not be accessed directly using direct member access operator (.). We will learn how private and protected members can be accessed.

    Classes and Objects in Detail

    So far, you have got very basic idea about C++ Classes and Objects. There are further interesting concepts related to C++ Classes and Objects which we will discuss in various sub-sections listed below −

    Sr.NoConcept & Description
    1Class Member FunctionsA member function of a class is a function that has its definition or its prototype within the class definition like any other variable.
    2Class Access ModifiersA class member can be defined as public, private or protected. By default members would be assumed as private.
    3Constructor & DestructorA class constructor is a special function in a class that is called when a new object of the class is created. A destructor is also a special function which is called when created object is deleted.
    4Copy ConstructorThe copy constructor is a constructor which creates an object by initializing it with an object of the same class, which has been created previously.
    5Friend FunctionsA friend function is permitted full access to private and protected members of a class.
    6Inline FunctionsWith an inline function, the compiler tries to expand the code in the body of the function in place of a call to the function.
    7this PointerEvery object has a special pointer this which points to the object itself.
    8Pointer to C++ ClassesA pointer to a class is done exactly the same way a pointer to a structure is. In fact a class is really just a structure with functions in it.
    9Static Members of a ClassBoth data members and function members of a class can be declared as static.
  • Object Oriented

    The prime purpose of C++ programming was to add object orientation to the C programming language, which is in itself one of the most powerful programming languages.

    The core of the pure object-oriented programming is to create an object, in code, that has certain properties and methods. While designing C++ modules, we try to see whole world in the form of objects. For example a car is an object which has certain properties such as color, number of doors, and the like. It also has certain methods such as accelerate, brake, and so on.

    There are a few principle concepts that form the foundation of object-oriented programming −

    Object

    This is the basic unit of object oriented programming. That is both data and function that operate on data are bundled as a unit called as object.

    Class

    When you define a class, you define a blueprint for an object. This doesn’t actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object.

    Abstraction

    Data abstraction refers to, providing only essential information to the outside world and hiding their background details, i.e., to represent the needed information in program without presenting the details.

    For example, a database system hides certain details of how data is stored and created and maintained. Similar way, C++ classes provides different methods to the outside world without giving internal detail about those methods and data.

    Encapsulation

    Encapsulation is placing the data and the functions that work on that data in the same place. While working with procedural languages, it is not always clear which functions work on which variables but object-oriented programming provides you framework to place the data and the relevant functions together in the same object.

    Inheritance

    One of the most useful aspects of object-oriented programming is code reusability. As the name suggests Inheritance is the process of forming a new class from an existing class that is from the existing class called as base class, new class is formed called as derived class.

    This is a very important concept of object-oriented programming since this feature helps to reduce the code size.

    Polymorphism

    The ability to use an operator or function in different ways in other words giving different meaning or functions to the operators or functions is called polymorphism. Poly refers to many. That is a single function or an operator functioning in many ways different upon the usage is called polymorphism.

    Overloading

    The concept of overloading is also a branch of polymorphism. When the exiting operator or function is made to operate on new data type, it is said to be overloaded.

  • Function Overriding in C++

    A function is a collection of code blocks with instructions inside, which is used for specific tasks. It is meant to be reused as per requirement, making the division of complex problems into smaller and manageable pieces.

    What is Function Overriding in C++?

    Function overriding is a concept of object-oriented programming which allows a derived class to redefine a function that is already defined in the base class.

    Here the method’s name and parameters remain the same, but the derived class changes its behavior to suit their specific needs.

    Example

    Let’s consider these 2 functions; one is base class (a) and another is derived class (b), and the function (c) is the main(), where we are implementing overriding −

    Function (a)

    classbase{public:voidnotice()
       cout <<"This is my Base Class";}

    Function (b)

    classderived:public base{public:voidnotice()
    
      cout &lt;&lt;"This is my Derived Class";}</code></pre>

    Function (c)

    voidmain(){// creating an object for base class and calling it
       base b;
       b.notice();// creating an object for derived class and calling it 
       derived d ;
       d.notice();}

    Overriding Explanation

    • Here, we have created an object of base and derived class of 'function (a) and function(b)' respectively and called them inside function (c) as shown, "b.notice() and d.notice()" respectively.
    • In this case, for derived class d.notice() will be executed first because it represents the most up-to-date or updated version of the function
    • However, if we create an object of the base class as shown in function(c) "b.msg()" and call it, it will use the original version from the base class.

    In short, function overriding occurs when the functionality of the base class is redefined in the derived class. When an object of the derived class is created, it will call the updated function from the derived class, meaning that the base class function (a) is overridden by the derived class function (b).

    Function overriding is an essential concept in object-oriented programming, enabling polymorphism and dynamic binding.

    Example of Function Overriding

    Below is a simple example illustrating how overriding works

    #include <iostream>usingnamespace std;// Base classclassShape{public:// Virtual method to be overriddenvirtualvoiddraw()const{
    
         cout &lt;&lt;"Drawing a shape"&lt;&lt; endl;}};// Derived class CircleclassCircle:public Shape{public:// Overriding the base class methodvoiddraw()constoverride{
         cout &lt;&lt;"Drawing a circle"&lt;&lt; endl;}};// Derived class SquareclassSquare:public Shape{public:// Overriding the base class methodvoiddraw()constoverride{
         cout &lt;&lt;"Drawing a square"&lt;&lt; endl;}};// Main functionintmain(){
    Shape* shapePtr; Circle circle; Square square;// Point to Circle and call draw() shapePtr =&circle; shapePtr->draw();// Outputs: Drawing a circle// Point to Square and call draw() shapePtr = □ shapePtr->draw();// Outputs: Drawing a squarereturn0;}

    Output

    Drawing a circle
    Drawing a square
    

    Function Overriding Vs. Function Overloading

    Although Function Overriding and Function Overloading are essential key-concepts of Object-oriented programming in C++, they both do serve different purposes.

    Function overriding allows derived class to get new implementation of method to its previously defined base class, as having different scopes(base class and derived class) where it resolved at runtime polymorphism(dynamic binding), it only take place in presence of inheritance and can overridden just once, where execution speed relatively slower.

    Whereas, function overloading enables you to create multiple functions with the same name but different parameter lists within the same scope. It is resolved at compile time polymorphism (static binding), where presence of inheritance is not important, These functions can be overloaded multiple times and execution speed tends to be faster comparatively.

    Advanced Overriding Concepts

    Here’s a list of additional sub topics covering advanced overriding concepts −

    1. Virtual Destructor

    A virtual destructor makes sure that the destructor of the derived class will be executed when an object is removed through a base class pointer. Function overriding with virtual destructors avoids resource leaks and unpredictable behavior by ensuring proper deletion of objects through base class pointers.

    Example

    Open Compiler

    #include <iostream>usingnamespace std;classBaseClass{public:virtual~BaseClass(){// Virtual destructor
    
         cout &lt;&lt;"BaseClass destructor"&lt;&lt; endl;}};classDerivedClass:public BaseClass{public:~DerivedClass()override{// Overriding destructor
         cout &lt;&lt;"DerivedClass destructor"&lt;&lt; endl;}};intmain(){
    BaseClass* a =newDerivedClass();// Calls DerivedClass's destructor followed// by BaseClass's destructordelete a;return0;}

    Output

    DerivedClass destructor
    BaseClass destructor
    

    2. Covariant Return Value Types

    Covariant return types allow derived classes to override a method and return a more specific type than the base class method. This means that a derived class can return a pointer or reference to a more derived type, rather than just the base type. Function overriding improves flexibility and precision in object-oriented programming.

    Note

    In the derived class, the return type must be a pointer or reference to a type that is derived from the return type of the base class.

    Example

    Open Compiler

    #include <iostream>usingnamespace std;classVehicle{public:// Final methodvirtualvoidhonk()final{
    
         cout &lt;&lt;"Vehicle honk: Beep beep!"&lt;&lt; endl;}};classSportsCar:public Vehicle{// Cannot override honk() here};intmain(){
    Vehicle* v =newSportsCar(); v->honk();// Calls Vehicle's honk() methoddelete v;return0;}

    Output

    Vehicle honk: Beep beep!
    

    3. Overriding and final Keyword alternate word

    The final keyword stops any further subclassing of a class or overriding of a method.

    Function overriding with the final keyword is important because it guarantees that a class or method cannot be further changed or extended.

    Example

    Open Compiler

    #include <iostream>usingnamespace std;classSubject{public:// Final methodvirtualvoidexamType()final{
    
         cout &lt;&lt;"This subject has a written exam."&lt;&lt; endl;}};classMath:public Subject{// Cannot override examType() here};intmain(){
    Subject* s =newMath(); s->examType();// Calls Subject's examType() methoddelete s;return0;}

    Output

    This subject has a written exam.
    

    4. Virtual Inheritance

    Virtual inheritance in C++ tackles problems which arise with multiple inheritance, particularly the diamond problem. It ensures that when a class inherits from several base classes which have a common ancestor, only a single instance of that common base class is created.

    Virtual inheritance makes sure that only one copy of a base class is used when multiple derived classes share that base class in a hierarchy.

    Example

    Open Compiler

    #include <iostream>usingnamespace std;classBase{public:voidpresent(){ cout <<"Display from Base class"<< endl;}};classA:virtual public Base{};classB:virtual public Base{};classFinal:public A, public B{public:voidget(){ cout <<"Display from Final class"<< endl;}};intmain(){
       Final obj;// Displays: Display from Base class
       obj.present();// Displays: Display from Final class
       obj.get();return0;}

    Output

    Display from Base class
    Display from Final class
    

    Advantages of Function Overriding

    1. Polymorphism

    Overriding enables polymorphism by letting objects of different derived classes be treated as instances of a base class. This allows dynamic method binding at runtime, where the correct method implementation is chosen based on the object type, thus enhancing flexibility and adaptability, making it a fundamental component of polymorphism.

    2. Code Reusability

    Developers can utilize existing code by inheriting methods from a base class and customizing them in derived classes. This approach fosters a more streamlined and organized code structure.

    3. Maintainability

    Overriding promotes a modular design by encapsulating various functionalities within distinct classes. This approach simplifies understanding, maintaining, updating and extending the code.

    4. Design Patterns

    Overriding plays a key role in the Template Method pattern by defining the overall structure of an algorithm in a base class, while permitting subclasses to override specific steps.

    The Strategy pattern leverages overriding to encapsulate various algorithms and enable their interchange at runtime.

    5. Memory Management

    When using inheritance and dynamic memory allocation, virtual destructors are vital for proper memory management. Overriding the destructor in derived classes ensures that resources allocated by the base and derived classes are correctly deallocated, which prevents memory leaks and ensures clean resource release.