У меня нет вашего компилятора, и это сильно зависит от компилятора и опций.В g ++ 4.5 с параметрами по умолчанию (и после исправления нескольких проблем в коде) я скомпилировал в ассемблер (g++ -S -o test.asm test.cpp
) код, и он показывает функции и вызовы через механизм виртуальной диспетчеризации (в main
)после вызова конструктора он извлекает vptr, смещает его и вызывает через значение в регистре).
Определение Shape :: function2 (обратите внимание, что .weak означает inline )
.globl __ZN5Shape9function2Ev
____.weak_definition __ZN5Shape9function2Ev
__ZN5Shape9function2Ev:
[...]
Определение Shape :: function1 (опять же, слабое означает inline )
.globl __ZN5Shape9function1Ev
____.weak_definition __ZN5Shape9function1Ev
__ZN5Shape9function1Ev:
[...]
Определение самого vtable для Shape:
.globl __ZTV5Shape
.weak_definition __ZTV5Shape
.section __DATA,__const_coal,coalesced
.align 5
__ZTV5Shape:
.quad 0
.quad __ZTI5Shape # Ptr to type_info object
.quad __ZN5Shape9function1Ev # vtable[0] is Shape::function1
.quad __ZN5Shape9function2Ev # vtable[1] is Shape::function2
Определение main:
.globl _main
_main:
[...]
movq %rax, %rbx
movq %rbx, %rdi
call __ZN5ShapeC1Ev # Call to constructor this will setup the vptr
movq %rbx, -24(%rbp)
movq -24(%rbp), %rax # load **vptr into rax i.e. *vptr[0]: Shape::function1
movq (%rax), %rax
movq (%rax), %rax
movq -24(%rbp), %rdi
call *%rax # call it
Что говорят другие, что компилятор можетполностью исключить виртуальную диспетчеризацию или встроить функцию, это правда.Эта версия g ++ не делает это для этого конкретного куска кода, но удаляет указатель (используя Shape
со статической продолжительностью хранения)