Причина запроса порядка вызова деструктора. - PullRequest
3 голосов
/ 31 августа 2010

Как я читал на некоторых форумах, когда создается объект производного класса, члены базового класса и методы распределяются в памяти, но нет конкретного объекта базового класса.

Теперь, когда объект производного класса выходит из области видимости, почему деструктор производного класса вызывается первым. Каково ограничение компилятора, когда деструктор производного класса не может быть вызван после деструктора базового класса ..?

Пожалуйста, поправьте меня, если я неправильно понял ... Заранее спасибо

Ответы [ 4 ]

7 голосов
/ 31 августа 2010

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

7 голосов
/ 31 августа 2010

Когда создается объект производного класса, равен конкретному объекту базового класса (на самом деле подобъекту). То есть, когда вы создаете производный объект, ctor базового класса используется для инициализации subj-объекта базового класса в производном объекте, и только после того, как это завершится, ctor производного класса выполняет свою задачу, инициализируя любые члены, добавленные в производный класс и т. д.

Так как он построен от основания к производному, он сносится от производного к основанию. Когда производный dtor завершает выполнение, все равно должен быть совершенно корректный базовый объект, ожидающий, пока базовый dtor уничтожит его. Однако, если вы сначала попытались уничтожить базовый подобъект, когда вы запустили производный dtor, у вас больше не было бы действительного производного объекта для уничтожения производного dtor.

5 голосов
/ 31 августа 2010

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

Предположим, у вас есть класс Y, который наследуется от Xи класс Z, который наследуется от Y.По принципам объектно-ориентированного наследования каждый Y равен X.И каждый Z является a Y и X.

Посмотрите, что происходит при удалении объекта типа Z, если деструкторы вызываются из самых производных в базу:

  • Сначала выполняется деструктор Z,Объект перестает быть Z и превращается в Y.

  • Затем выполняется деструктор Y.Объект перестает быть Y и снова превращается в X.

  • Затем выполняется деструктор X.Объект перестает быть X и теперь вообще ничем (полностью уничтожен).

Теперь рассмотрим, что произойдет, если вместо этого сначала был вызван базовый деструктор:

  • Сначала выполняется деструктор X.Объект перестает быть X.

Теперь, что это за объект?Это не X, но это также не может быть Y, поскольку Y - это и X.Это не может быть Z, поскольку Z тоже и X!На данный момент объект не имеет четко определенного типа, и поэтому вызов другого метода, даже другого деструктора, приведет к поведению, которое невозможно определить.

Говоря более конкретно: вполне возможно, чтоДеструктору Z или деструктору Y требуется доступ к чему-то, что определено в классе X.Так что деструктор X должен запускаться последним.Обратите внимание, что в другом направлении проблем нет, поскольку базовый класс X не может получить доступ к чему-либо в своих производных классах.

0 голосов
/ 04 февраля 2011

Есть небольшой трюк, который вы можете использовать: Деструкторы членов производного класса называются после весь стек деструкторов был вызван.

Я перепроверил сейчас член типа std :: map и это не соответствует действительности. ЖАЛЬ.

...