Почему деструктор производного класса вызывается по константной ссылке на базовый класс? - PullRequest
8 голосов
/ 13 февраля 2011

В ответе GMan здесь деструктор класса restore_base не virtual, поэтому я продолжаю задаваться вопросом, как именно это работает. Обычно вы ожидаете, что деструктор restorer_base будет выполнен только после того, как объект выйдет из области видимости, но кажется, что производный деструктор restorer_holder действительно вызывается. Кто-нибудь хочет меня просветить?

1 Ответ

18 голосов
/ 13 февраля 2011

Стандартный случай, когда вам нужен виртуальный деструктор:

void foo()
{
   scoped_ptr<Base> obj = factory_returns_a_Derived();

   // ... use 'obj' here ...
}

И стандартный случай, когда вы не равен

void foo()
{
   Derived obj;

   // ... use 'obj' here ...
}

Код GManделать что-то более хитрое, что оказывается эквивалентным второму случаю:

void foo()
{
   Base& obj = Derived();

   // ... use 'obj' here ...
}

obj - голая ссылка;как правило, это не будет вызывать деструкторы вообще.Но он инициализируется из анонимного временного объекта, чей статический тип - известный компилятору - Derived.Когда время жизни этого объекта заканчивается, компилятор вызывает деструктор Derived.Обычно анонимный временный объект умирает в конце выражения , которое его создало, но есть особый случай для временных инициализирующих ссылку: они живут до тех пор, пока не умирает сама ссылка, что здесь является концом области действия.Таким образом, вы получаете псевдо- scoped_ptr поведение и вам не нужен виртуальный деструктор.

РЕДАКТИРОВАТЬ: Так как теперь это происходит дважды: ссылка не должно быть const для применения этого специального правила.C + 98 [class.teven] / 5:

Второй контекст [в котором временный объект не уничтожается в конце полного выражения] - это когда ссылка связан с временным.Временный объект, к которому привязана ссылка, или временный объект, являющийся полным объектом для подобъекта, к которому привязан временный объект, сохраняется в течение времени жизни ссылки ...

Акцент мой.На этом языке нет упоминания const, поэтому ссылка не должна быть const.

РЕДАКТИРОВАТЬ 2: Другие правила в стандарте запрещают создание неконстантныхссылки на временные объекты, которые не являются lvalues.Я подозреваю, что по крайней мере некоторые временные объекты являются значениями, но я точно не знаю.Независимо от того, , что не влияет на это правило .Формально все равно было бы верно, что неконстантные ссылки на временные объекты продлевают время их жизни , даже если никакая строго соответствующая C ++ программа не сможет создать такую ​​ссылку.Это может показаться смешным, но вы предположительно читаете это буквально и педантично.Каждое слово имеет значение, каждое слово, которого там нет, имеет значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...