对于为什么析构函数从派生到基础调用的最佳答案?

时间:2011-10-14 03:55:18

标签: destructor

我最近参加了一次采访,那个人问我什么是建筑和破坏的顺序。我解释说,施工发生在从基地到儿童和从儿童到基地的破坏。

面试官热衷于知道从派生到基地发生破坏是否有任何特殊原因。我解释了他,但他不相信。

他的观点是,如果基类破坏给出异常,派生类如何知道派生类对象将如何被破坏。

他还告诉派生类包含基类成员,为什么我们不能先调用基类破坏?

我解释说,在派生类破坏完成后,我们不能说对象被完全破坏了。

我在这儿吗?这里最好的答案是什么?

3 个答案:

答案 0 :(得分:2)

你是对的。在采访经验丰富的C ++程序员时,我常常经常问这个问题。必须在基类之后构造派生类,以便派生类构造函数可以引用基类数据。出于同样的原因,派生类析构函数必须在基类析构函数之前运行。这是非常合乎逻辑的:我们从内到外构造,并从外部进行破坏。如果基类析构函数抛出异常,则它不能被派生类析构函数捕获。基类构造函数中的异常也不能由派生类构造函数处理。通常,不应该从析构函数中抛出异常。

答案 1 :(得分:1)

在C#对象构造中遵循以下顺序:

  1. 数据成员的初始化Derived - >基地
  2. 构造函数库的执行 - >的。
  3. 为什么呢?

    • 初始化遵循Derived - >以避免在衍生自基础时以不同方式初始化的成员的重新初始化为基础。
    • 构建遵循基础 - >派生,因为Derived构造函数可能依赖于Base类的方法。

    其他语言处理初始化的方式不同,但Base->衍生建筑是典型的。

    销毁是从Derived完成的 - >基

    为什么?

    • Derived可能仍然依赖于基地在销毁期间分配的资源。

      • 如果首先销毁Base,则Derived将不再使用这些资源。
    • 层次结构的每个级别都应负责释放该级别分配的任何资源。

      • Base无法释放Derived Class的资源,因为它不了解它们。
      • 派对也不应对基地分配的资源负责
        • 在严格的OOP中,派生者甚至不知道这些资源的详细信息,或者他们分配或发布的方式。

    回应他的具体观点:

    • 基地的例外情况
      • 不应该在析构函数中抛出异常(特别是在C#中,这至少会同时杀死垃圾收集器)
    • 派生类包含基类成员
      • 该对象具有任何数据成员的一个实例。每层次的层次结构都不是一个 因此,如果基类释放与数据成员关联的资源,我们将返回,它将不再可供Derived类使用。

    您对订单推理的解释。如果我们假设Derived-> Base顺序是正确的,那么这就解释了为什么你仍然必须调用Base析构函数,而不是为什么Derived首先出现。
    如果对订单的担忧不同,并且销毁完成了Base-> Derived,那么我们将能够在Derived析构函数完成后完全破坏对象,因为在所有级别都会发生破坏。

答案 2 :(得分:0)

重要的是要理解对象构造分阶段进行。如果你有一个从A派生的B类,你首先构造一个A,然后将A转换为B来构造B.同样,B首先将其转换为A,然后销毁A来销毁。这提供了关于对象创建和破坏的非常一致的思考方式。