Есть ли какое-либо различие между защищенным и частным деструктором в C++? Если деструктор базовых классов является частным, я предполагаю, что это все еще называют при удалении объекта производного класса.
Взято из здесь:
Если конструктор/деструктор объявлен как частный, то класс не может быть инстанцирован.
Это верно, однако он может быть инстанцирован из другого метода класса. Аналогично, если деструктор является private
, то объект может быть удален только внутри класса. Кроме того, это предотвращает наследование класса (или, по крайней мере, предотвращает инстанцирование/уничтожение наследуемого класса).
Ответ заключается в том, что ваше предположение неверно. Деструктор базового класса не может быть вызван, когда он является закрытым.
Если деструктор базового класса является private
или protected
, то вы не можете вызвать delete
через указатель базового класса.
Используйте защищенный деструктор для предотвращения уничтожения производного объекта через указатель базового класса. Это ограничивает доступ к деструктору для производных классов. И это предотвращает автоматическое (стека) объектов класса base.
По сути, он используется для того, чтобы позволить любому другое полиморфное использование производных классов через указатели на базу, но не позволять пользователям удалять, используя такой указатель. Пример:- Абстрактные базовые классы / интерфейсы.
Но защищенный
, невиртуальный
деструктор кажется ошибкой, которая только и ждет своего часа. Если предположить, что вы не предоставляете функцию destroy()
, то в конечном итоге вам придется сделать деструктор общедоступным. Как только вы это сделаете, у вас больше не будет контроля над классом, и вы рискуете получить полиморфное удаление с невиртуальным dtor, если от вашего класса будет получено дальнейшее производное.
Следующий фрагмент кода приведет к ошибке компилятора (VC2010): C2248: 'base :: ~ base': не может получить доступ к закрытому члену, объявленному в классе 'base'
class base
{
~base(){}
};
class derived : public base
{
};
int main ()
{
derived* d = new derived;
delete d;
}
Однако, если вы измените базовый деструктор для защиты, все будет работать нормально.