Это не ответ, а скорее более подробное объяснение мотивации вопроса.Я не хочу загромождать сам вопрос этим несколько касательным материалом.
Вот объяснение того, как я ожидал бы обычную последовательность уничтожения производного класса с членами.Предположим, что класс таков:
class Base
{
public $x;
// ... (constructor, destructor)
}
class Derived extends Base
{
public $foo;
// ... (constructor, destructor)
}
Когда я создаю экземпляр $z = new Derived;
, он сначала создает подобъект Base
, затем объекты-члены Derived
(а именно $z->foo
),и, наконец, конструктор Derived
выполняется.
Поэтому я ожидал, что последовательность уничтожения произойдет в совершенно противоположном порядке:
execute Derived
деструктор
уничтожить объекты-члены Derived
выполнить Base
деструктор.
Однако, посколькуPHP не вызывает базовые деструкторы или базовые конструкторы неявно, это не работает, и мы должны сделать явный вызов базового деструктора внутри производного деструктора.Но это расстраивает последовательность уничтожения, которая теперь «производная», «базовая», «члены».
Вот мое беспокойство: если какой-либо из объектов-членов требует, чтобы состояние базового подобъекта было действительным для ихсобственной операции, то ни один из этих объектов-членов не может полагаться на этот базовый подобъект во время их собственного уничтожения, потому что этот базовый объект уже был признан недействительным.
Является ли это подлинной проблемой или в языке есть что-то, что мешаеттакие зависимости происходят?
Вот пример на C ++, который демонстрирует необходимость правильной последовательности уничтожения:
class ResourceController
{
Foo & resource;
public:
ResourceController(Foo & rc) : resource(rc) { }
~ResourceController() { resource.do_important_cleanup(); }
};
class Base
{
protected:
Foo important_resource;
public:
Base() { important_resource.initialize(); } // constructor
~Base() { important_resource.free(); } // destructor
}
class Derived
{
ResourceController rc;
public:
Derived() : Base(), rc(important_resource) { }
~Derived() { }
};
Когда я создаю экземпляр Derived x;
, тогда сначала создается базовый подобъект, который устанавливает important_resource
.Затем объект-член rc
инициализируется со ссылкой на important_resource
, которая требуется при уничтожении rc
.Поэтому, когда время жизни x
заканчивается, производный деструктор сначала вызывается (ничего не делая), затем rc
уничтожается, выполняет свою работу по очистке, и только затем является уничтоженным подобъектом Base
,освобождение important_resource
.
Если уничтожение произошло не по порядку, деструктор rc
получил бы недопустимую ссылку.