- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在学习 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 对象系统从不要求 正确的销毁序列,我将为此提供另一个赏金(或仅针对任何其他有说服力的答案)。
最佳答案
我想解释为什么 PHP 以这种方式运行,以及为什么它实际上有(某些)意义。
在 PHP 中,一旦不再有对对象的引用,对象就会被销毁。可以通过多种方式删除引用,例如通过 unset()
变量,通过离开范围或作为关闭的一部分。
如果你理解了这一点,你就可以很容易地理解这里发生了什么(我会先解释没有异常的情况):
$x
创建的引用(到 Der
的实例)被删除时,对象被销毁。$this->foo
到 Foo
实例的引用被删除(作为销毁成员字段的一部分。)Foo
的引用,因此它也被销毁并调用析构函数。想象一下,这不会以这种方式工作,并且成员字段会在调用析构函数之前被销毁:您无法再在析构函数中访问它们。我严重怀疑 C++ 中是否存在这种行为。
在异常情况下,您需要了解对于 PHP 而言,类的实例从未真正存在过,因为构造函数从未返回。你怎么能破坏从未 build 过的东西?
我该如何解决?
你不知道。你需要一个析构函数这一事实可能是糟糕设计的标志。事实上,销毁命令对您来说非常重要,这一点更重要。
关于php - PHP 类构造函数中的作用域展开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7470969/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!