Calling virtual member functions in a constructor, although this is not a very common technique, research can deepen the understanding of virtual function mechanism and object construction process. This problem is also different from the general intuitive understanding. Look at the following two class definitions first.
struct C180
{
C180() {
foo();
this->foo();
}
virtual foo() {
cout << "<< C180.foo this: " << this << " vtadr: " << *(void**)this << endl;
}
};
struct C190 : public C180
{
C190() {}
virtual foo() {
cout << "<< C190.foo this: " << this << " vtadr: " << *(void**)this << endl;
}
};
There is a virtual function in the parent class, and the parent class invokes the virtual function in its constructor, which takes two approaches when invoked, one in direct invocation and the other through the this pointer. The subclass also rewrites the virtual function.
We can predict what happens if a C190 object is constructed.
We know that when you construct an object, you first get a piece of memory (on the heap or stack) at the object's size, and then the pointer to that memory is invoked as the this pointer to invoke the class's constructor to initialize the memory. If the object has a parent class, it first invokes the constructor of the parent class (and then recursively), if more than one parent class (multiple inheritance) calls the constructor of the parent class in turn, and adjusts the position of this pointer appropriately. After you call the constructor of all the parent classes, execute your own code.
The C180 constructor is also invoked when the above analysis constructs the C190, when the first Foo in the C180 constructor is called a static binding, and the C180::foo () function is invoked. The second Foo call is invoked by a pointer, where the polymorphic behavior occurs and the C190::foo () function should be invoked.
Execute the following code:
C190 obj;
obj.foo();
The results are:
<< C180.foo this: 0012F7A4 vtadr: 0045C404
<< C180.foo this: 0012F7A4 vtadr: 0045C404
<< C190.foo this: 0012F7A4 vtadr: 0045C400