Inheritance in C++ is similar to Java, allowing the creation of a class hierarchy. It enables a derived (child) class to inherit attributes and behaviors from a base (parent) class.
A derived class can inherit methods and fields from a base class, except those marked as private.
class Animal {
public:
void walk() {
std::cout << "Animal walks" << std::endl;
}
};
class Dog : public Animal {
public:
void bark() {
std::cout << "Dog barks" << std::endl;
}
};Here, Dog extends Animal, inheriting the walk method.
The inheritance relationship is established using : followed by the access specifier (public, protected, or private).
class User {
public:
std::string userName;
void login() {
// login code
}
};
class Instructor : public User {
public:
std::string batchName;
double avgRating;
void scheduleClass() {
// schedule class code
}
};Instructor extends User, inheriting userName and login().
Like Java, C++ also has constructor chaining, where the base class constructor is called before the derived class constructor.
class A {
public:
A() {
std::cout << "Constructor of A" << std::endl;
}
};
class B : public A {
public:
B() {
std::cout << "Constructor of B" << std::endl;
}
};
class C : public B {
public:
C() {
std::cout << "Constructor of C" << std::endl;
}
};
int main() {
C c; // This will print constructors of A, B, and C in order.
}In C++, the equivalent of Java's super is the base class constructor call. It's used with the base class name and parentheses.
class C : public B {
public:
C(std::string message) : B() {
std::cout << "Constructor of C with message: " + message << std::endl;
}
};The B() constructor is explicitly called from C's constructor.
Like Java, C++ uses inheritance to support abstraction. Abstract classes in C++ are created using pure virtual functions.
C++ provides more control over inheritance through three types of access: public, protected, and private.
- public inheritance: The most common form, where public and protected members of the base class remain public and protected in the derived class.
- protected inheritance: Public and protected members of the base class become protected in the derived class.
- private inheritance: Public and protected members of the base class become private in the derived class.
Unlike Java, C++ supports multiple inheritance, where a class can inherit from more than one base class. This feature can be powerful but also introduces complexity, such as the "diamond problem."
class Base1 {
public:
void function1() {}
};
class Base2 {
public:
void function2() {}
};
class Derived : public Base1, public Base2 {
// Inherits function1 from Base1 and function2 from Base2
};C++ uses virtual functions to enable polymorphism, a core concept in OOP. A virtual function in a base class can be overridden in a derived class to provide specific behavior. Virtual functions are crucial for achieving runtime polymorphism.
class Base {
public:
virtual void show() {
std::cout << "Base class show" << std::endl;
}
};
class Derived : public Base {
public:
void show() override {
std::cout << "Derived class show" << std::endl;
}
};An abstract class in C++ is a class that has at least one pure virtual function. Pure virtual functions are declared by assigning 0 to them, and they must be overridden in derived classes.
class AbstractBase {
public:
virtual void pureVirtualFunction() = 0; // Pure virtual function
};
class ConcreteClass : public AbstractBase {
public:
void pureVirtualFunction() override {
// implementation
}
};The diamond problem occurs in multiple inheritance when two classes B and C inherit from A, and class D inherits from both B and C. This creates ambiguity regarding which A class members D should inherit. C++ resolves this using virtual inheritance.
class A {
public:
void functionA() {}
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {
// D now has a single copy of A's members
};In C++, the constructors of base classes are called in the order of inheritance, and destructors are called in the reverse order. Understanding this order is crucial for proper resource management in more complex class hierarchies.