Home > Backend Development > C++ > Why Does Calling a Virtual Function in a Base Class Constructor Result in the Base Class Implementation Being Used?

Why Does Calling a Virtual Function in a Base Class Constructor Result in the Base Class Implementation Being Used?

Barbara Streisand
Release: 2024-12-21 02:03:15
Original
776 people have browsed it

Why Does Calling a Virtual Function in a Base Class Constructor Result in the Base Class Implementation Being Used?

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
}
Copy after login

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.

  • Maturation: As an object is constructed, it starts with the base class constructors and gradually "matures" into the derived class type.

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:

  1. 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;
    Copy after login
  2. 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
    Copy after login
  3. 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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template