C++ Inheritance
One of the most important concepts in object-oriented programming is inheritance. Inheritance allows us to define a class based on another class, which makes creating and maintaining an application easier. This also achieves the effect of reusing code functionality and improving execution efficiency.
When creating a class, you do not need to rewrite new data members and member functions; you only need to specify that the new class inherits the members of an existing class. This existing class is called the base class, and the new class is called the derived class.
Inheritance represents an is a relationship. For example, mammals are animals, dogs are mammals, therefore, dogs are animals, and so on.
Code example:
// Base class
class Animal {
// eat() function
// sleep() function
};
// Derived class
class Dog : public Animal {
// bark() function
};
Base Class & Derived Class
A class can be derived from multiple classes, meaning 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 classes. The class derivation list names one or more base classes and is in the following form:
class derived-class: access-specifier base-class
Where the access specifier 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, it defaults to private.
Suppose there is a base class Shape, and Rectangle is its derived class, as shown below:
Example
#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);
// Output 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. Therefore, members of the base class that do not want to be accessed by members of the derived class should be declared as private in the base class.
We can summarize the different access types based on access permissions, as shown below:
Access | public | protected | private |
---|---|---|---|
Same class | yes | yes | yes |
Derived class | yes | yes | no |
External class | yes | no | no |
A derived class inherits all the base class methods with the following exceptions:
- The base class's constructors, destructors, and copy constructors.
- The base class's overloaded operators.
- The base class's friend functions.
Inheritance Types
When a class is derived from a base class, the base class can be inherited as public, protected, or private. The inheritance type is specified by the access specifier access-specifier
discussed above.
We rarely use protected or private inheritance; public inheritance is commonly used. When using different types of inheritance, the following rules apply:
- Public Inheritance (public): When a class is derived from a public base class, the base class's public members are also public members of the derived class, and the base class's protected members are also protected members of the derived class. The base class's private members cannot be directly accessed by the derived class, but can be accessed by calling the base class's public and protected members.
- Protected Inheritance (protected): When a class is derived from a protected base class, the base class's public and protected members become protected members of the derived class.
- Private Inheritance (private): When a class is derived from a private base class, the base class's public and protected members become private members of the derived class.
Multiple Inheritance
Multiple inheritance allows a subclass to have multiple parent classes, inheriting characteristics from all of them.
A C++ class can inherit members from multiple classes with the following syntax:
class <DerivedClassName>:<InheritanceMode1><BaseClassName1>,<InheritanceMode2><BaseClassName2>,…
{
<DerivedClassBody>
};
Here, the access specifier inheritance mode can be public, protected, or private, used to modify each base class, and base classes are separated by commas, as shown above. Now, let's look at the following example:
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();
// Output the area of the object
cout << "Total area: " << Rect.getArea() << endl;
// Output the total cost
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