C++ 3d.Комментарии

       

Свободная память


// полагаем, что p указывает на s байтов памяти, выделенной Employee::operator new()

Данное предположение не вполне корректно: p также может являться нулевым указателем, и в этом случае определяемый пользователем operator delete() должен корретно себя вести, т.е. ничего не делать.

Запомните: определяя operator delete(), вы обязаны правильно обрабатывать удаление нулевого указателя! Т.о. код должен выглядеть следующим образом: void Employee::operator delete(void* p, size_t s) { if (!p) return; // игнорируем нулевой указатель

// полагаем, что p указывает на s байтов памяти, выделенной // Employee::operator new() и освобождаем эту память // для дальнейшего использования }

Интересно отметить, что стандартом специально оговорено, что аргумент p функции template <class T> void std::allocator::deallocate(pointer p, size_type n);

не может быть нулевым. Без этого замечания использование функции Pool::free в разделе 19.4.2. "Распределители памяти, определяемые пользователем" было бы некорректным.


В принципе, освобождение памяти осуществляется тогда внутри деструктора (который знает размер).

Именно так. Т.е. если вы объявили деструктор некоторого класса A::~A() { // тело деструктора }

то компилятором (чаще всего) будет сгенерирован следующий код // псевдокод A::~A(A *const this, bool flag) { if (this) { // тело деструктора if (flag) delete(this, sizeof(A)); } }

Ввиду чего функция void f(Employee* ptr) { delete ptr; }

превратится в // псевдокод void f(Employee* ptr) { Employee::~Employee(ptr, true); }

и т.к. класс Employee имеет виртуальный деструктор, это в конечном итоге приведет к вызову соответствующего метода.



Содержание раздела