Lesson content
Read, practise, then check your understanding
A virtual function selects the most-derived override at runtime when called through a base reference or pointer. A pure virtual function uses = 0; a class with any unimplemented pure virtual operation is abstract and cannot be instantiated.
#include <string_view>
class Logger {
public:
virtual ~Logger() = default;
virtual void write(std::string_view message) = 0;
virtual void flush() {}
};
class ConsoleLogger final : public Logger {
public:
void write(std::string_view message) override;
};
Keep interfaces narrow and describe preconditions, ownership, and exception behavior. Prefer a public virtual destructor or a protected non-virtual destructor; public non-virtual destruction invites incomplete deletion through a base pointer.
Dispatch details
Default arguments are selected from the static type, while the virtual function body is selected dynamically, so avoid changing defaults in overrides. Calls made from constructors and destructors do not dispatch to more-derived overrides because that portion is not yet alive or has already been destroyed.
Private virtual functions can still be overridden; access control is checked at the call expression, separate from dispatch. The non-virtual interface pattern exposes a public stable operation that validates input and calls a protected/private customization point. Avoid storing polymorphic objects by value; use references for observation and smart pointers for ownership.
Knowledge check
Answer every question correctly to complete this chapter.
0 of 10 checks passed
Your progress is saved on this device.