ScholarQuill logoScholarQuillUniversity Notes
  • Notes
  • Past Papers
  • Blogs
  • Todo
Login
ScholarQuill logoScholarQuillUniversity Notes
Login
NotesPast PapersBlogsTodo
More
SubjectsDiscussionCGPA CalculatorGPA CalculatorStudent PortalCourse Outline
About
About usPrivacy PolicyReportContact
Notes
Past Papers
Blogs
Todo
Analytics
    Current Subject
    🧩
    Object Oriented Programming
    COMP2111
    Progress0 / 23 topics
    Topics
    1. Introduction to object oriented design2. History and advantages of object oriented design3. Introduction to object oriented programming concepts4. Classes and objects5. Data encapsulation6. Constructors and destructors7. Access modifiers8. Const vs non-const functions9. Static data members & functions10. Function overloading11. Operator overloading12. Identification of classes and their relationships13. Composition and aggregation14. Inheritance15. Multiple inheritance16. Polymorphism17. Abstract classes and interfaces18. Generic programming concepts19. Function & class templates20. Standard template library21. Object streams22. Data and object serialization using object streams23. Exception handling
    COMP2111›Polymorphism
    Object Oriented ProgrammingTopic 16 of 23

    Polymorphism

    7 minread
    1,211words
    Intermediatelevel

    Polymorphism in C++

    Polymorphism is a key concept in Object-Oriented Programming (OOP) that allows one interface to be used for a general class of actions. In simple terms, polymorphism means "many forms". In C++, polymorphism allows objects of different types to be treated as objects of a common base type, providing flexibility and reusability in code. It is one of the four fundamental OOP concepts, alongside encapsulation, inheritance, and abstraction.

    Types of Polymorphism in C++

    There are two main types of polymorphism in C++:

    1. Compile-time Polymorphism (Static Polymorphism)
    2. Run-time Polymorphism (Dynamic Polymorphism)

    1. Compile-time Polymorphism (Static Polymorphism)

    Compile-time polymorphism occurs when the method to be called is resolved at compile time. The most common ways to achieve compile-time polymorphism in C++ are:

    • Function Overloading
    • Operator Overloading

    Function Overloading:

    Function overloading allows multiple functions with the same name but different parameters (either in number or type) to exist in the same scope. The appropriate function is selected based on the number and types of arguments passed.

    Example of Function Overloading:

    #include <iostream>
    using namespace std;
    
    class Display {
    public:
        void show(int i) {
            cout << "Integer: " << i << endl;
        }
        void show(double d) {
            cout << "Double: " << d << endl;
        }
        void show(string s) {
            cout << "String: " << s << endl;
        }
    };
    
    int main() {
        Display obj;
        obj.show(10);         // Calls show(int)
        obj.show(3.14);       // Calls show(double)
        obj.show("Hello");    // Calls show(string)
        return 0;
    }
    

    Explanation:

    • The show function is overloaded with three different versions: one that accepts an integer, one that accepts a double, and one that accepts a string.
    • The compiler decides which show function to call based on the argument passed. This decision happens at compile time, so it's compile-time polymorphism.

    Operator Overloading:

    Operator overloading allows you to define custom behavior for operators (like +, -, *, etc.) when they are used with objects of a class.

    Example of Operator Overloading:

    #include <iostream>
    using namespace std;
    
    class Complex {
    public:
        int real, imag;
    
        Complex() : real(0), imag(0) {}
    
        // Overload the "+" operator
        Complex operator + (const Complex& other) {
            Complex temp;
            temp.real = real + other.real;
            temp.imag = imag + other.imag;
            return temp;
        }
    
        void display() {
            cout << real << " + " << imag << "i" << endl;
        }
    };
    
    int main() {
        Complex c1, c2, result;
        c1.real = 3; c1.imag = 4;
        c2.real = 1; c2.imag = 2;
    
        result = c1 + c2;  // Calls the overloaded "+" operator
        result.display();   // Output: 4 + 6i
    
        return 0;
    }
    

    Explanation:

    • The operator + is overloaded to add two Complex numbers. When you use the + operator between c1 and c2, the overloaded function is called.
    • This is an example of compile-time polymorphism because the operator behavior is determined at compile time.

    2. Run-time Polymorphism (Dynamic Polymorphism)

    Run-time polymorphism occurs when the method to be called is determined at runtime. This type of polymorphism is achieved through inheritance and virtual functions.

    Run-time polymorphism allows you to invoke derived class methods through a base class pointer or reference. It is also called method overriding and is commonly used with virtual functions.

    Virtual Functions:

    A virtual function is a function in the base class that is overridden in the derived class. The key feature of a virtual function is that the type of the object being referred to (rather than the type of the pointer or reference) determines which function is called.

    • Base class function: Declared as virtual in the base class.
    • Derived class function: Overrides the base class function.

    When you use a base class pointer or reference to call a virtual function, the appropriate derived class function is called based on the type of the object, not the type of the pointer.

    Example of Run-time Polymorphism:

    #include <iostream>
    using namespace std;
    
    class Animal {
    public:
        virtual void sound() {
            cout << "Animal makes a sound" << endl;
        }
    };
    
    class Dog : public Animal {
    public:
        void sound() override {
            cout << "Dog barks" << endl;
        }
    };
    
    class Cat : public Animal {
    public:
        void sound() override {
            cout << "Cat meows" << endl;
        }
    };
    
    int main() {
        Animal* animalPtr;
    
        Dog dog;
        Cat cat;
    
        animalPtr = &dog;
        animalPtr->sound();  // Calls Dog's sound() function
    
        animalPtr = &cat;
        animalPtr->sound();  // Calls Cat's sound() function
    
        return 0;
    }
    

    Explanation:

    • The sound() function is virtual in the Animal base class. It is overridden in the Dog and Cat derived classes.
    • An Animal* pointer is used to call the sound() function. At runtime, the type of the object (dog or cat) determines which version of sound() is called.
    • When the pointer animalPtr points to a Dog object, the Dog's version of sound() is called. Similarly, when it points to a Cat object, the Cat's version of sound() is called.
    • This is run-time polymorphism because the method that gets called is determined at runtime, not at compile time.

    Key Concepts in Polymorphism:

    1. Virtual Function:

      • A function in the base class that can be overridden in the derived class.
      • Declared with the virtual keyword in the base class.
      • The decision about which function to call is made at runtime based on the object type.
    2. Function Overriding:

      • A derived class provides its own implementation of a function that is already defined in the base class.
      • When you use a base class pointer or reference to call the overridden function, the version of the function for the actual object type is called.
    3. Function Overloading (Compile-time Polymorphism):

      • Multiple functions with the same name but different parameter types or numbers of parameters.
      • The function to call is resolved at compile time.
    4. Operator Overloading (Compile-time Polymorphism):

      • Overloading operators like +, -, *, etc., to perform operations on user-defined types.
      • The overloaded operator is resolved at compile time.

    Benefits of Polymorphism:

    1. Code Reusability:

      • Polymorphism allows for code reuse, as the same function or operator can work with different types of objects.
      • It reduces the need for duplicate code.
    2. Flexibility and Maintainability:

      • Polymorphism enables you to write flexible code that works with objects of different types, allowing changes and extensions with minimal modifications to the existing code.
    3. Improved Design:

      • It helps in designing systems that are easy to extend. For example, you can add new derived classes without modifying the existing code that uses polymorphism.

    Summary of Polymorphism:

    • Polymorphism is the ability of one function or operator to behave differently based on the object it operates on.
    • Compile-time polymorphism (static polymorphism) is achieved through function overloading and operator overloading.
    • Run-time polymorphism (dynamic polymorphism) is achieved using virtual functions and method overriding.
    • Virtual functions enable run-time polymorphism, where the function to be called is determined at runtime, depending on the actual object type.

    Polymorphism is a powerful feature of OOP that allows for the creation of flexible and reusable code.

    Previous topic 15
    Multiple inheritance
    Next topic 17
    Abstract classes and interfaces

    Past Papers

    Open this section to load past papers

    Click on Show Past Papers to see past papers.
    On This Page
      Reading Stats
      Est. reading time7 min
      Word count1,211
      Code examples0
      DifficultyIntermediate