Overriding Virtual Functions in Constructors
Consider the following code snippet:
#include <iostream> struct base { virtual const int value() const { return 0; } base() { // Default constructor std::cout << value() << std::endl; } }; struct derived : public base { virtual const int value() const { return 1; } }; int main() { derived d; // Declares an instance of the derived class }
When we run this code, it prints 0 instead of the expected 1. Why?
Virtual Function Call During Construction
When a base class constructor invokes a virtual function in the constructor, the virtual function is called on the base class instance rather than the derived class instance. This is a result of the 'maturation' process of the object during construction.
In our example, the base constructor calls value() when the object is partially constructed. At this point, the object has not yet "matured" into a derived object. Thus, the original base implementation of value() is called.
How to Fix the Issue
To make the code print 1, you can avoid calling the virtual function in the constructor. This can be achieved by:
Using a Pointer: Call the virtual function from a pointer or reference to the base class instead of directly from its member function:
base* b = new derived(); b->value(); // Calls the derived class implementation delete b;
Using a Member Initialization List: Use a member initialization list to explicitly specify the value of the virtual function in the constructor:
derived d : base() { } // Initializes `base()` and the virtual function // call to occur within the constructor
The above is the detailed content of Why Does Calling a Virtual Function in a Base Class Constructor Result in the Base Class Implementation Being Used?. For more information, please follow other related articles on the PHP Chinese website!