我正在学习 PHP 类和异常,而且由于我的 C++ 背景,以下内容让我感到奇怪:
当派生类的构造函数抛出异常时,似乎基类的析构函数不会自动运行:
class Base
{
public function __construct() { print("Base const.\n"); }
public function __destruct() { print("Base destr.\n"); }
}
class Der extends Base
{
public function __construct()
{
parent::__construct();
$this->foo = new Foo;
print("Der const.\n");
throw new Exception("foo"); // #1
}
public function __destruct() { print("Der destr.\n"); parent::__destruct(); }
public $foo; // #2
}
class Foo
{
public function __construct() { print("Foo const.\n"); }
public function __destruct() { print("Foo destr.\n"); }
}
try {
$x = new Der;
} catch (Exception $e) {
}
这将打印:
Base const.
Foo const.
Der const.
Foo destr.
另一方面,如果构造函数中出现异常(在#1
处),则成员对象的析构函数将被正确执行。现在我想知道:如何在PHP类层次结构中实现正确的作用域展开,以便在发生异常时可以正确销毁子对象?
此外,似乎没有办法在所有成员对象都被销毁后运行基类的析构函数(在#2
处)。也就是说,如果我们删除#1
行,我们会得到:
Base const.
Foo const.
Der const.
Der destr.
Base destr.
Foo destr. // ouch!!
如何解决这个问题?
更新:我仍然欢迎更多的贡献。如果有人能够充分证明为什么PHP对象系统从来没有强制要求正确的销毁顺序,我将再次提供奖励(或者对其他具有说服力的回答进行奖励)。