liveBook · Manning

Inheritance

As explained in 100 C++ Mistakes and How to Avoid Them

Inheritance is a C++ language mechanism by which a derived class acquires and can extend members and behavior from base classes.

Inheritance lets a derived class acquire and extend behavior from a base class, but code reuse alone is not a sound reason to introduce it. Public inheritance should express an is-a relationship: wherever a base object is required, the derived object must remain substitutable. Poor hierarchies create exceptions, obscure behavior, and maintenance work. section 7.7 section 8.1

Treat inheritance as a correctness and maintenance decision, not merely a reuse technique:

  • Check the Liskov substitution principle before deriving one class from another; apparent similarities do not establish an is-a relationship. section 7.7
  • Remember that a derived object combines the data parts of its base and derived classes, so constructors, destructors, and operators must manage every part. section 8.7
  • When a polymorphic base can be deleted through a pointer, provide a virtual destructor; otherwise deletion has undefined behavior and may skip derived cleanup. section 8.8
  • Avoid duplicating base knowledge in overriding methods; call an appropriate base implementation when it forms part of the derived class's basis. section 7.5

The derived assignment that forgets its base

A Student is a Person with additional state. An assignment operator that copies only gpa leaves the destination's inherited name unchanged: assigning Thelma to Louise produces two different names with the same grade point average. Delegate the base portion first, then copy the derived portion: Person::operator=(o); gpa = o.gpa;. This pattern matters beyond explicit assignments because copying can occur through vector or array operations. section 8.7

The base pointer that deletes incorrectly

Shape is polymorphic because area is virtual. Creating a Square through Shape* and deleting that pointer requires Shape's destructor to be virtual. Without it, the output shows only ~Shape; with the virtual destructor, destruction proceeds through ~Square and then ~Shape. The hierarchy's base-class design therefore affects every derived type. section 8.8

Listing 7.13 Using an interface-like class
class Moveable {                                             #1
public:
    virtual void move(int) = 0;
    virtual double getPosition() = 0;
};
 
class Square : public Moveable {
private:
    double side;
    double offset;
public:
    Square(double side) : side(side), offset(0) {}
    void move(int n) { this->offset += n*side; }             #2
    double getPosition() { return offset; }
    double area() { return side*side; }
};
 
class Horse : public Moveable {
private:
    double height;
    double position;
public:
    Horse(double height) : height(height), position(0) {}
    void move(int offset) { position += offset; }            #3
    double getPosition() { return position; }
};
 
int main() {
    std::vector<Moveable*> movers;                           #4
    movers.push_back(new Square(1));
    movers.push_back(new Horse(15));
    for (int i = 0; i < movers.size(); ++i) {
        movers[i]->move(2);
        std::cout << "Mover moved " << movers[i]->getPosition() << " units \n";
    }
    return 0;
}

Compare unrelated Square and Horse classes through a small Moveable interface, rather than forcing inheritance from a misleading common implementation class. section 7.7

How 100 C++ Mistakes and How to Avoid Them covers it

How deep it goes
Explains public inheritance, substitutability, object data parts, assignment, method reuse, and virtual destruction through worked examples.
Examples
Uses Person and Student copying, Shape and Square destruction, and Square and Horse movement to expose hierarchy mistakes.
What it assumes
Assumes basic C++ classes, pointers, references, virtual functions, and operators while developing hierarchy reasoning through concrete examples.
What you can do after
Diagnose inheritance defects involving substitutability, copied base state, duplicated behavior, and deletion through polymorphic base pointers.
How it connects
Connects inheritance with the Liskov substitution principle, polymorphism, class invariants, copy assignment operators, and virtual destructors.

Also explained in

Compare how 19 books explain inheritance →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 C++ Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.