Re[4]: Самоудаляющиеся объекты
От: Кодт Россия  
Дата: 12.01.05 11:28
Оценка:
Здравствуйте, Nikopol, Вы писали:

N>Если делать деструктор защищённым, то это ровным счётом ничего не меняет.

N>Компилятор это проглатывает.
N>Если сделать приватным, то тогда компилятор ругается на попытки объявить деструкторы у наследников.

Разумеется. И это не глюки.
Просто, если у наследника деструктор не определён явно, то его определяет компилятор, причём публичным. И тут — лишь бы деструктор базы был доступен наследнику.
class B1
{
  ~B1() {} // недоступен потомкам
};
class D11 : public B1
{
  // деструктор не определён явно, и если его не вызывают (скалярно или по delete), то не определён вообще
  // объект невозможно разрушить
};
class D12 : public B1
{
  ~D12() {} // ошибка: деструктор предка недоступен
};
void foo1()
{
  D11 d; // ошибка: требуется деструктор
  D11* pd = new D11(); // сколько угодно
  delete pd; // ошибка: требуется деструктор
  delete (B*)pd; // ошибка: деструктор приватный; без неё был бы баг (недоразрушение потомка)
}

class B2
{
protected:
  ~B1() {} // доступно потомкам
};
class D21
{
  // неявно определённый деструктор будет публичным
};
class D22
{
protected:
  ~D22() {} // только таким способом мы прячем деструктор
};
void foo2()
{
  D21 d1; // в лучшем виде
  D22 d2; // ошибка
  D22 *p = new D22;
  delete p; // ошибка
}

class B3
{
  virtual ~B3() {} // приватный деструктор, но из-за врождённой багофичи С++ он доступен для перекрытия
};
class D31
{
  // Неявно определённый деструктор будет виртуальным и публичным.
  // Поскольку перегрузка взламывает права доступа, деструктор предка стал доступен деструктору потомка
};
class D32
{
protected:
  ~D32() {} // только таким способом мы прячем деструктор; он, разумеется, продолжает быть виртуальным
};
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.