Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Почему порядок уничтожения данных объекта должен быть обратным к порядку их конструирования?

#cpp #ооп #конструктор #деструктор


Заинтересовал вопрос: а почему порядок уничтожения данных объекта должен быть обратным
к порядку их конструирования? Нельзя ли удалять содержимое объекта в другой последовательности,
отличной от порядка их конструирования? Не связано ли это как-то с выравниванием данных
или с хранением ссылок на функции-члены (поправьте, если выражаюсь некорректно)? Если
есть возможность, предоставьте ссылку на источник. Благодарю!
    


Ответы

Ответ 1



Порядок удаления обратен порядку конструирования по вполне естественным причинам: в процессе конструирования и/или удаления между разными объектами могут существовать взаимозависимости. Если объект А во время своего конструирования полагался на то, что объект Б уже полностью сконструирован, то в процессе деструкции объекта A желательно было бы гарантировать объекту А, что объект Б ещё не деструктирован. Из этого естественным образом вытекает обратный порядок удаления. В случае, когда речь идет о подобъектах объекта класс-типа такая гарантия выглядит более чем естественно: в теле конструктора/деструктора классу, разумеется, нужно, чтобы его подобъекты были уже/еще работоспособны. В более общем случае (например, взаимный порядок создания/удаления разных статических объектов) аналогичные зависимости между разными объектами могут формироваться во время выполнения, то есть никаких шансов предсказать их наличие или доказать их отсутствие у компилятора нет. Поэтому разумным решением видится гарантировать глобальную упорядоченность настолько, насколько это возможно.

Ответ 2



В плюсах есть такое понятие как исключение. При не плановом возврате из функций остаётся не разобранный стек объектов. При очистке стека нужно вызывать деструкторы локальных переменных. Эти деструкторы будут вызываться по порядку декларации в программе и исключение не имеет информации удалён ли объект до этого. По-этому чтобы всё правильно очистилось пишется данная рекомендация. Стандарт : As control passes from a throw-expression to a handler, destructors are invoked for all automatic objects constructed since the try block was entered. The automatic objects are destroyed in the reverse order of the completion of their construction. An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object has completed execution and a delegating constructor for that object exits with an exception, the object’s destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object. Перевод: По мере того, как управление переходит от throw-выражения к обработчику, деструкторы вызываются для всех автоматических объектов, созданных с момента ввода блока try. Автоматические объекты уничтожаются в порядке, обратном завершению их строительства. У объекта любой продолжительности хранения, инициализация или уничтожение которого завершается исключением, будут деструкторы, выполняемые для всех его полностью построенных подобъектов (исключая альтернативные члены объединяющего класса), то есть для подобъектов, для которых главный конструктор ( 12.6.2) завершил выполнение, а деструктор еще не начал выполнение. Точно так же, если не делегирующий конструктор для объекта завершил выполнение и делегирующий конструктор для этого объекта завершается с исключением, будет вызван деструктор объекта. Если объект был выделен в новом выражении, соответствующая функция освобождения (3.7.4.2, 5.3.4, 12.5), если таковая имеется, вызывается для освобождения памяти, занятой объектом.

Ответ 3



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

Комментариев нет:

Отправить комментарий