Understanding Explicit Function Overriding
A derived function only overrides a base function when the base class has a virtual function with the same name, so a misspelled name does not get corrected and instead causes an error.
A Prediction Before the Explanation
Many learners assume that a small spelling mistake in a derived function's name is harmless. The reasoning goes like this: the derived class clearly meant to replace a function from its base class, so the language will probably work out the intended name and connect the two. Under that belief, a slightly misspelled name would be ignored or quietly corrected, and the program would behave as if the spelling were right. This belief is wrong, and it is one of the most frequent sources of confusion in class hierarchies.
What do you think happens?
A base class has a virtual function named draw. A derived class declares a function named drw, meaning it tried to override draw but misspelled it. When draw is called through a base-class reference, which function runs?
Reveal answer
The base draw function runs. The derived drw does not override anything, so it is simply a separate function that the base-class call never reaches.
Overriding depends on the base class having a virtual function with the same name. Because drw does not match draw, the derived class has no override, and the call made through the base reference still dispatches to the base version. The mismatch is not corrected by the language.
Why a Misspelled Name Is Not Corrected
A derived function overrides a base function only when the base class has a virtual function with the same name. A misspelled name does not get corrected. It becomes a declaration that does not line up with anything in the base class.
The key idea is that overriding is a matching relationship. The base class declares a virtual function, and the derived class supplies a replacement that is connected to it by name. When the name does not match, there is no connection. The derived class still compiles, because it is legal to add a new function with any name, but that new function is unrelated to the base function. Calls that go through the base class continue to reach the base version.
This is why the source describes the misspelled case as causing an error rather than a fix. The derived function is not promoted to an override. Its effect on the base-class interface is nothing at all, and the program's behavior is not what the author intended. The bug is silent: nothing in the declaration itself announces that anything went wrong.
Tracing a Call Through a Base Reference
Read the program below and follow the call one step at a time. The object is a Circle, but the variable that calls draw has the type Shape&, a reference to the base class. The question is which draw function the call reaches.
Shape::draw- Shape::draw is declared virtual, so it is the function that derived classes may override
- Circle::drw has a different name, so it does not override Shape::draw
- ref has type Shape&, so
ref.draw()is a call made through the base-class interface - The output comes from the base version, because nothing in Circle replaces draw
Trace the call step by step. Step 1: ref.draw() is looked up through the Shape interface. Step 2: Shape declares a virtual draw, so the call is eligible to reach a derived version. Step 3: Circle has no function called draw, only drw, so there is no derived replacement. Step 4: the call reaches Shape::draw, and the program prints Shape::draw. The drw function was written, compiled, and never called.
Comparing a Matching Name and a Misspelled Name
The two versions of the hierarchy differ by one letter, but they lead to opposite outcomes. The diagram below sets the matching case beside the misspelled case. In the matching case, the derived declaration connects to the base virtual function, so a call through the base reference reaches the derived code. In the misspelled case, the derived function is a separate function, and the base version runs.
What the override Keyword Checks
The first safeguard against this silent failure is simply to state intent. The override keyword can be written on a declaration to say that the function is meant to override a base virtual function. The keyword does more than document intent, though. It asks the compiler to confirm that the declaration really does override a base virtual function, and it reports an error when that confirmation fails.
This turns a silent mistake into an immediate one. Without the keyword, a misspelled declaration compiles and the bug only appears later, when the wrong function runs. With the keyword, the same declaration is rejected as soon as it is compiled, at the point where the mistake was made. The diagram below shows the decision the compiler makes when it sees the keyword.
Adding the override Keyword to a Mistyped Declaration
Take the same hierarchy as before and add the override keyword to the misspelled declaration. The before and after versions show how the outcome changes. The first version compiles and runs silently. The second version is rejected, because drw is marked as an override but does not override anything in the base class.
class Circle : public Shape {
public:
void drw() const {
std::cout << "Circle::drw\n";
}
};Compiles. drw is a separate function, and ref.draw() prints Shape::draw.
class Circle : public Shape {
public:
void drw() const override {
std::cout << "Circle::drw\n";
}
};Compile-time error. drw is marked override, but nothing in Shape matches it.
Correcting the Misspelled Declaration
The override keyword has rejected drw in Circle. Apply a correction so that Circle really overrides Shape::draw, then predict the output of the same main function.
- 1Read the compiler error
The error says that drw is marked override but does not override a base function. This means the name has no match in Shape.
- 2Compare against the base declaration
Shape declares virtual void
draw()const. The name in the derived class must be draw, not drw. - 3Correct the name
Rename the derived function to draw and keep the same parameter list and const qualifier, so that the declaration lines up with the base function.
- 4Re-check the call
With the name matching and override present, the compiler accepts the declaration. A call through Shape& now reaches the derived code.
After the correction, the derived declaration is void draw() const override, and ref.draw() prints Circle::draw. The override keyword now confirms the connection instead of rejecting it.
Circle::draw- The name now matches the base virtual function draw
- The const qualifier matches the base declaration
- override asks the compiler to confirm the match
Common Overriding Mismatches
The misspelled name is only one of several ways a derived declaration can fail to line up with the base class. The source identifies the shared root cause as a declaration that does not match anything in the base class. The mistakes below all share that cause, and each one can be caught by the override keyword.
Common mistake Misspelling the derived function's name
What it looks likeDeclaring drw in Circle when the base declares virtual void draw() const
Why it failsThe derived function never connects to the base virtual function, so base-class calls never reach it.
Do this insteadUse the exact base name draw and mark the declaration override.
Common mistake Dropping the const qualifier
What it looks likeDeclaring void draw() override in Circle when the base declares virtual void draw() const
Why it failsA declaration without the matching const qualifier does not line up with the base function, so it does not override it. With override present, the compiler reports an error.
Do this insteadCopy the full declaration from the base class, including the const qualifier, and keep override.
Common mistake Forgetting that the base function must be virtual
What it looks likeBase declares void draw() const without virtual, and Circle declares void draw() const override
Why it failsThe base function is not a virtual function, so there is nothing for the derived declaration to override. The override keyword reports the mismatch.
Do this insteadDeclare the base function virtual, or remove override if no overriding is intended.
Common mistake Changing the parameter list
What it looks likeBase declares virtual void draw() const, and derived declares void draw(int scale) const override
Why it failsThe derived function has a different parameter list, so it is not the same function as the base function and does not override it.
Do this insteadMatch the base parameter list exactly, or give the new function a different name if it is genuinely a new operation.
Where Overriding Fits in the Hierarchy
A class hierarchy connects a derived class to a base class. The derived class can replace behavior that the base class defines, and the overriding rules describe when that replacement counts. The source introduces a discussion of the benefits of hierarchies but does not spell out those benefits in the passage provided, so this article does not name them. What the surrounding material does establish is that the name-matching and override checks exist to keep the replacement honest: a derived function replaces a base behavior only when it is clearly connected to it.
Practice Predicting an Override Failure
A base class declares virtual void speak() const. A derived class declares void spek() const override. Without running the code, decide what the compiler does with the derived declaration, and then say which function a call such as ref.speak() would reach through a base reference.
Hints
- Compare the derived name letter by letter with the base name.
- The override keyword asks the compiler to confirm a match. What does it report when no match exists?
- If the derived declaration is rejected, there is no derived version for a base-class call to reach.
Key Takeaways
- A derived function overrides a base function only when the base class has a virtual function with the same name, so a misspelled name is not corrected and does not override anything.
- A call made through a base-class reference reaches the derived version only when the override succeeds. A misspelled derived function is a separate function that base-class calls never reach.
- The override keyword asks the compiler to confirm that a declaration really overrides a base virtual function, and it reports an error when the confirmation fails, turning a silent bug into an immediate one.
- Overriding mistakes share one root cause: a declaration that does not line up with anything in the base class. The fix is to correct the declaration so that its name, parameters, and qualifiers match the base function.