Class Inheritance and Polymorphism

Class Basics

In C++, a class is a user-defined data type that encapsulates data (members) and functions (methods) to organize related data and behavior. Classes allow developers to create objects that represent real-world entities, such as vehicles, animals, or complex data structures. A class defines the structure of an object, including its attributes (variables) and behaviors (functions).

Class Members and Methods

A class can have public, protected, or private members, which control access to the data and functions. Public members are accessible from anywhere, protected members are accessible within the class and derived classes, and private members are only accessible within the class itself. Methods are functions defined within a class and can be accessed via object instances.

Inheritance

Inheritance is a core feature of C++ that allows a class (called a derived class) to inherit properties and methods from another class (called a base class). This promotes code reuse and hierarchical relationships.

Access Specifiers in Inheritance

The access specifiers (public, protected, private) determine how members are accessed in the derived class. For example:

  • Public inheritance (using public): All members of the base class are public in the derived class.
  • Protected inheritance (using protected): Members are protected in the derived class.
  • Private inheritance (using private): Members are private in the derived class.

Multiple Inheritance

C++ supports multiple inheritance, where a class can inherit from multiple base classes. This allows for more flexible hierarchies but can lead to the "diamond problem" (multiple inheritance conflicts).

Virtual Functions

Virtual functions enable polymorphic behavior, allowing derived classes to override base class methods. A virtual function is declared with virtual in the base class and overridden in derived classes.

Polymorphism

Polymorphism allows objects of different classes to be treated as objects of a common interface. It is achieved through compile-time (static) and runtime (dynamic) binding.

Compile-Time Polymorphism

This is achieved via overloading (function with the same name but different parameters) and templates. Overloading allows multiple functions with the same name but different signatures, while templates enable generic code that works with any data type.

Runtime Polymorphism

This is achieved via virtual functions. When a derived class overrides a base class method, the actual method executed depends on the object's runtime type.

Example: Animal Class

class Animal {
public:
    virtual void sound() { cout << "Unknown animal sound" << endl; }
    virtual ~Animal() {}
};
class Dog : public Animal {
public:
    void sound() override { cout << "Bhow!" << endl; }
};
class Cat : public Animal {
public:
    void sound() override { cout << "Meow!" << endl; }
};

Objects of Dog and Cat can be stored in a vector<Animal*>, and their sound() methods are called based on their actual type.

Advanced Topics

Virtual Base Classes

To avoid the diamond problem in multiple inheritance, virtual base classes are used. A virtual base class is declared in multiple base classes and ensures only one instance exists, even if the class is inherited from multiple sources.

Abstract Classes

An abstract class is a class that cannot be instantiated and must be inherited. It includes at least one abstract method (a method with a virtual declaration but no implementation). Abstract classes enforce interface implementation and are often used as blueprints for derived classes.

Templates

Templates allow writing generic code that works with any data type. A template is defined with template <typename T>, and functions or classes can be specialized for specific types.

Conclusion

Class inheritance and polymorphism are fundamental concepts in C++ that enable efficient code organization and flexibility. Inheritance allows code reuse through hierarchical relationships, while polymorphism enables objects to be treated as objects of different types. Understanding these concepts is essential for developing scalable and maintainable C++ applications.