Что этот дополнительный параметр передал в виртуальный деструктор?
У меня есть этот код:
class Class {
public:
virtual ~Class() {}
};
int main()
{
Class* object = new Class();
delete object;
}
который я компилирую с Visual С++ 10 и получаю эту разборку для оператора delete object
:
delete object;
test eax,eax
je wmain+23h (401041h)
mov edx,dword ptr [eax]
push 1
mov ecx,eax
call dword ptr [edx]
и это для фактического деструктора:
Class::`scalar deleting destructor':
test byte ptr [esp+4],1
push esi
mov esi,ecx
mov dword ptr [esi],offset Class::`vftable' (402100h)
je Class::`scalar deleting destructor'+18h (401018h)
push esi
call dword ptr [__imp_operator delete (4020A8h)]
pop ecx
mov eax,esi
pop esi
ret 4
Что такое push 1
делает на сайте вызова и почему test
в точке входа деструктора проверяет это значение и условно обходит вызов на operator delete()
?
Ответы
Ответ 1
Аргумент используется деструктором, чтобы узнать, должен ли он в конце удалить вызов.
3 случая, когда вы не хотите называть это:
- Деструктор вызывается деструктором производного класса
- Объект выделяется в стеке, поэтому он не создается с новым.
- Объект - это поле другого объекта, которое не создано новым
EDIT: добавьте третий случай
Ответ 2
Я полагаю, что дополнительный параметр сообщает компилятору, какой деструктор является производным, самый лучший, так что он только освобождает память один раз, на соответствующем уровне наследования. Я видел что-то подобное в gcc, если я правильно помню.
Ответ 3
В принципе, виртуальный деструктор также реализует удаление вызывающего оператора. Параметр должен решить, следует ли его вызывать.
См. этот ответ, который показывает значение такого скрытого параметра деструктора.