Skip to main content

Item 36: Never redefine an inherited non-virtual function

Concept

Non-virtual functions are statically bound, meaning the function called depends on the declared type of the pointer or reference, not the actual runtime type of the object. Redefining a non-virtual function in a derived class creates inconsistent behavior: calling the function through a base pointer invokes the base version, while calling through a derived pointer invokes the derived version — for the same object. This violates the is-a relationship that public inheritance asserts and creates confusion.

Code Example

class Base {
public:
void doWork() { /* Base version */ }
};

class Derived : public Base {
public:
void doWork() { /* Derived version — DON'T DO THIS */ }
};

// The problem:
Derived d;
Base* bp = &d;
Derived* dp = &d;

bp->doWork(); // Calls Base::doWork — static binding!
dp->doWork(); // Calls Derived::doWork
// Same object, different behavior depending on pointer type

Full source code

Things to Remember

  • Never redefine an inherited non-virtual function.
  • Item 32 — Public inheritance models is-a (non-virtual redefinition breaks this)
  • Item 34 — Non-virtual functions specify mandatory inherited implementation
  • Item 37 — Never redefine inherited default parameter values (related static binding issue)