简体   繁体   中英

C++ child constructor and VPTR

In many sources, books etc. are written "don't call this->virtualFunction in child class constructor" and in some sources explain why you mustn't do it. Because at the moment of construction class isn't created at all. So virtual function that will be called from child constructor will be function of base class. It means that in child constructor body VPTR of that class pointed to base VTABLE.

So my question is,
what is the moment in object construction when VPTR of child class will be overriden to address on it's virtual table? I guess that some automatically generated code do it at end of constructor body or after constructor body will be executed.

And second question is,
why is VPTR overriden at the end of construction? Maybe for it have some important reasons? Why can't override VPTR at beginning constructor body or after base class constructed?

Child::Child() :
Base()
//<----- Why not here?
//members initialization
{
//<----- Why not here?
//code
}

I disagree with your overly simplified reason to why you shouldn't call a virtual function. First of all, a VTABLE is not actually defined by the C++ standard, and is, in fact, implementation specific:

When is VTable in C++ created?

Calling a virtual function from a constructor is allowed by the standard, and should actually should call correctly within the hirearchy at that level (with some limitations)

C++ constructors: why is this virtual function call not safe? http://www.parashift.com/c%2B%2B-faq-lite/calling-virtuals-from-ctors.html

However, there are many, many reasons not to do this.

  • The constructor for the derived class has not been called yet. Any access of any members of the derived class will yield undefined behavior.
  • There is a rule of thumb that you should keep constructors as simple and dumb as possible. This is due to the fact that error handling in constructors can be a giant pain due to destructor not being called and the only way to return a sensical error state is to throw an exception.
  • This will often break the dependency inversion principal, and may cross the line of demeter, and will usually introduce high coupling to the code.

In many sources, books etc. are written "don't call this->virtualFunction in child class constructor"

I doubt that. It's often advised not to call virtual functions from the base class constructor, to avoid confusion if you expect them to call the final overrides, not the base-class versions. And you must certainly not call them from the base class if they are pure virtual there - that gives undefined behaviour.

Within the derived class constructor, they are well-defined and do what you would expect.

So virtual function that will be called from child constructor will be function of base class.

No, during the child's constructor body, the dynamic type is Child , and virtual functions calls will use the Child overrides.

what is the moment in object construction when VPTR of child class will be overriden to address on it's virtual table?

After all base class constructors have completed, and before child class members are initialised. Child member functions, including virtual functions, can be called from member initialisers (but not base class initialisers) or the constructor body.

You need to be careful calling them from member initialisers, since they might access uninitialised members. But within the constructor body, all base objects and members are initialised, so they are quite safe.

why is VPTR overriden at the end of construction?

It isn't. It happens at the first point you indicate with <----- Why not here? .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM