See the following source code. Constructor, destructor and foo function contain the same codes.
{
foo(); // general function
v_foo(); // virtual function
}
But they produce a little different assembly codes.
#include <stdio.h>
class Object
{
virtual void temp1() {}
virtual void temp2() {}
virtual void temp3() {}
virtual void temp4() {}
virtual void temp5() {}
public:
void func()
{
printf(" func\n");
}
virtual void v_func()
{
printf(" v_func()\n");
}
public:
Object()
{
printf("Object::Object\n");
func(); // mov ecx, DWORD PTR _this$[ebp]
// call Object::func
v_func(); // mov ecx, DWORD PTR _this$[ebp]
// call Object::v_func // direct call
}
virtual ~Object()
{
printf("Object::~Object\n");
func(); // mov ecx, DWORD PTR _this$[ebp]
// call Object::func
v_func(); // mov ecx, DWORD PTR _this$[ebp]
// call Object::v_func // direct call
}
void foo()
{
printf("Object::foo\n");
func(); // mov ecx, DWORD PTR _this$[ebp]
// call Object::func
v_func(); // mov eax, DWORD PTR _this$[ebp]
// mov edx, DWORD PTR [eax]
// mov ecx, DWORD PTR _this$[ebp]
// mov eax, DWORD PTR [edx+20] // 20 == size of (temp1 ~ temp5)
// call eax // indirect call
}
};
int main()
{
Object* object = new Object;
object->foo();
delete object;
}
[Result]
In constructor and destructor, when virtual function is called, the function does not use it's virtual table(indirect address mode), but calls the specific static address directly(direct addressing mode).
[Download]
con_des_test.zip : Compiled in Microsoft Visual Studio 2005 Release mode ( Compile Option Optilization - Disabled (/Od) ).