This chapter describes the syntax and semantics of virtual functions, which are the way C++ does dynamic binding. Part II discusses dynamic binding and should be read before this chapter. Dynamic binding is an important concept, and most member functions should be virtual unless there is some compelling performance reason not to make them virtual or unless the programmer intentionally makes the member function a leaf (also known as final) member function (see FAQ 33.10).
A virtual member function is a member function preceded by the keyword virtual
or a member function with the same signature as a virtual function declared in a base class.
In this context, virtual
means “overridable.” More specifically, the keyword virtual
means that the runtime system automatically invokes the proper member function when it is overridden by a derived class (dynamic binding).
A member function should be made virtual when there will be derived classes that will need to provide their own implementation for the member function. This doesn't require as much clairvoyance as it seems to imply. Normally the virtual functions represent specifically architected places where extensibility is supposed to take place.
Overriding a virtual member function is also straightforward: simply declare the member function in the derived class and define a new implementation for that member function.
In theory, the overhead of dynamic binding is highly dependent on the compiler, operating system, and machine. In practice, almost all compilers do it the same way, and the overhead is very small.
A virtual function call typically costs 10% to 20% more than a nonvirtual function call. The overhead is smaller if there are several parameters, since the dynamic binding part of a virtual function call has constant cost. In practice, the overhead for the linkage of a function call is usually a very small percentage of the cost of the work that gets done, so the cost for a virtual function call is about the same as the cost for a normal function call.
For example, if a system or application spends 5% of its CPU utilization performing the linkage for function calls, and 25% of those calls are converted to virtual function calls, the additional overhead will be 10% of 25% of 5%, or around one-tenth of one percent overall.
If you can afford a normal function call, you can almost always afford a virtual function call.
Static typing ensures that all declarations, definitions, and uses of a virtual function are consistent while dynamic binding provides the “plumbing” so that the right implementation is called at runtime.
Given a reference (or pointer) to an object, there are two distinct types in question: the static type of the reference and the dynamic type of the referent (that is, the object being referred to). In other words, the object may be an instance of a class that is derived from the class of the reference. Nonvirtual (statically bound) member functions are selected based on the (statically known) type of the reference. Virtual (dynamically bound) member functions are selected based on the (dynamically known) type of the referent.
The legality of the call is checked based on the (statically known) type of the reference or pointer. This is safe because the referent must be “at least as derived as” the type of the reference. This provides the following type safety guarantee: if the class of the reference has the indicated member function, then the class of the referent will as well.
Yes, many destructors should be virtual.
Virtual destructors are extremely valuable when some derived classes have specified cleanup code. A practical, easy-to-remember guideline: if a class has any virtual functions, it should have a virtual destructor. The rationale for this is that if a class has no virtual functions, chances are the class designer wasn't planning on the class being used as a base class, so a virtual destructor is unnecessary.
Furthermore, on most compilers there is no additional per-object space cost after the first virtual function, so there is very little reason not to make the destructor virtual if the class already has at least one virtual function.
Note that this guideline is not precise enough for every circumstance, but the precise rule is much harder to remember. Here is the more precise rule: if any derived class (or any data member and/or base class of any derived class, or any base class of any data member of any data member of any derived class, or any data member of any base class of any data member of any derived class and all other recursive combinations of base classes and data members) has (or will ever have) a nontrivial destructor, and if any code anywhere deletes (or will ever delete) that derived class object via a base class pointer, then the base class's destructor needs to be virtual.
A virtual destructor causes the compiler to use dynamic binding when calling the destructor.
A destructor is called whenever an object is deleted, but there are some cases when the user code doesn't know which destructor should be called. For example, in the following situation, while compiling unawareOfDerived(Base*)
, the compiler doesn't even know that Derived
exists, much less that the pointer base
may actually be pointing at a Derived
.
Because Base::~Base()
is nonvirtual, only Base::~Base()
is executed and the Derived
destructor will not run. This could be a very serious error, especially if the Derived
destructor is supposed to release some precious resource such as closing a shared file or unlocking a semaphore.
The solution is to put the virtual
keyword in front of Base
's destructor. Once that is done, the compiler dynamically binds to the destructor, and thus the right destructor is always called:
class Base {
public:
virtual ~Base();
};
The virtual
keyword cannot be applied to a constructor since a constructor turns raw bits into a living object, and until there is a living object against which to invoke a member function, the member function cannot possibly work correctly. Instead of thinking of constructors as normal member functions on the object, imagine that they are static member functions (see FAQ 16.05) that create objects.
Even though constructors cannot actually be virtual
, a very simple idiom can be used to have the same effect. This idiom, called the virtual constructor idiom, allows the creation of an object without specifying the object's exact type. For example, a base class can have a virtual clone() const
member function (for creating a new object of the same class and for copying the state of the object, just like the copy constructor would do) or a virtual createSimilar() const
member function (for creating a new object of the same class, just as the default constructor would do).
Following is an example of this idiom (the return type is an auto_ptr
to help prevent memory leaks and wild pointers; see FAQ 32.01).
In Circle::createSimilar() const
and Circle::clone() const
, the kind-of relationship allows the conversion from a Circle*
to a Shape*
, then the Shape*
is converted to an auto_ptr<Shape>
(that is, to a ShapePtr
) by the auto_ptr
's constructor. In Circle::clone() const
, the expression new
Circle(*this)
calls Circle
's copy constructor, since *this
has type const Circle&
inside a const
member function of class Circle
.
Users can use clone
and/or createSimilar
as if they were virtual constructors. An example follows.
The output of this program follows.
main() number 1: Circle: radius=42
userCode() number 1: Circle: radius=42
userCode() number 2: Circle: radius=42
userCode() number 3: Circle: radius=0
Use the scope operator, ::
.
For example, if a constructor or a destructor of class Base
calls a virtual function this->f()
, it should call it using Base::f()
rather than merely f()
.
In our experience, this guideline reduces the probability that misunderstandings will introduce subtle defects, since it forces developers to explicitly state what the compiler is obliged to do anyway. In particular, when a constructor invokes a virtual member function that is attached to this
object, the language guarantees that the member function that is invoked is the one associated with the class of the constructor, even if the object being constructed will eventually be an object of a derived class that has its own version of the virtual function. An analogous statement can be made for calling a virtual function from a destructor.
The initialization list of Derived::Derived()
calls Base::Base()
, even if Base()
isn't explicitly specified in the initialization list. During Base::Base()
, the object is merely a Base
object, even though it will eventually be a Derived
object (see FAQ 20.14). This is why Base::f()
is called from the body of Base::Base()
. During the body of Derived::Derived()
, however, Derived::f()
is called. The output of this program is as follows.
Since developers are often somewhat surprised by this language feature, we recommend that such calls should be explicitly qualified with the scope operator, ::
.
::
be used when invoking virtual member functions?Only from derived classes, constructors, or destructors.
The purpose of the scope operator is to bypass the dynamic binding mechanism. Because dynamic binding is so important to users, user code should generally avoid using ::
. For example, the following prints Base::f()
even though the object is really a Derived
.
A pure virtual member function is a member function that the base class forces derived classes to provide. Normally these member functions have no implementation; but see FAQ 21.11.
A pure virtual member function specifies that a member function will exist on every object of a concrete derived class even though the member function is not (normally) defined in the base class. This is because the syntax for specifying a pure virtual member function forces derived classes to implement the member function if the derived classes intend to be instantiated (that is, if they intend to be concrete).
For example, all objects of classes derived from Shape
will have the member function draw()
. However, because Shape
is an abstract concept, it does not contain enough information to implement draw()
. Thus draw()
should be a pure virtual member function in Shape
.
This pure virtual function makes Shape
an abstract base class (ABC). Imagine that the “= 0
” is like saying “the code for this function is at the NULL
pointer.”
Pure virtual member functions allow users to write code against an interface for which there are several functionally different variants. This means that semantically different objects can be passed to a function if these objects are all under the umbrella of the same abstract base class.
Yes, but new C++ programmers don't usually understand what it means, so this practice should be avoided if the organization rotates developers.
If the goal is to create a member function that will be invoked only by derived classes (such as sharing common code in the abstract base class), create a protected:
nonvirtual function instead of using this feature. If the goal is to make something that may be callable from user code, create a distinctly named member function so that users aren't forced to use the scope operator, ::
.
The exception to this guideline is a pure virtual destructor in an ABC (see FAQ 21.13).
It should normally be defined as an inline
virtual function. An example follows.
The reason Base::~Base()
is inline is to avoid an unnecessary function call when Derived::~Derived()
automatically calls Base::~Base()
(see FAQ 20.05). In this case, Derived::~Derived()
is synthesized by the compiler.
Yes, provided the ABC (abstract base class) gives an explicit definition elsewhere. An example follows.
Leaving out a definition for Base::~Base()
will cause a linker error, because Derived::~Derived()
automatically calls Base::~Base()
(see FAQ 20.05). In this case, Derived::~Derived()
is synthesized by the compiler.
Depending on the compiler, there may be a marginal performance benefit in using a pure virtual destructor with an explicit inline definition versus the inline virtual technique that was described in the previous FAQ. Calls to inline virtual functions can be inlined if the compiler is able to statically bind to the class. However, the compiler may also make an outlined copy of an inline virtual function (for any other cases where it isn't able to statically bind to the call). Although in theory destructors of ABCs don't have these limitations, in practice not all compilers produce optimal code when using the inline virtual technique.
If a class has one or more virtual functions (either inherited or first-declared in that class), then the class should have at least one non-inline virtual function.
Many compilers use the location of the first non-inline virtual function to determine the source file that will house the class's magical stuff (the virtual table, out-lined copies of inline virtual functions, and so on). If all of the class's virtual functions are defined inline, these compilers may put a static copy of a class's magical stuff in every source file that includes the class's header file.
Note that this advice is fairly sensitive to the compiler. Some compilers won't generate copies of the magical stuff even if all the virtual functions in a class are inline. But even in these compilers, it doesn't cost much to ensure that at least one of the class's virtual functions is non-inline.
It is a good idea.
If the base class has a virtual destructor, the destructor in the derived class will also be virtual, and, unless specified otherwise, will be inline.
The safest bet is to give every derived class at least one non-inline virtual function (assuming the base class has a virtual destructor). To show how subtle this can be, consider this trivial example.
Even though no Base
or Derived
objects are created, the preceding example will fail to link on many systems. The reason is that the only virtual function in class Derived
is inline (Derived::~Derived()
is a synthesized inline virtual function), so the compiler puts a static
copy of Derived::~Derived()
into the current source file. Since this static
copy of Derived::~Derived()
invokes Base::~Base()
(see FAQ 20.05) the linker will need a definition of Base::~Base()
.
Adding a non-inline virtual function to a derived class (for example, thisDoesNothing()
) eliminates the linker errors for that derived class, because the compiler puts the (only) copy of the magical stuff into the source file that defines the non-inline virtual function.