我最近参加了一次采访,那个人问我什么是建筑和破坏的顺序。我解释说,施工发生在从基地到儿童和从儿童到基地的破坏。
面试官热衷于知道从派生到基地发生破坏是否有任何特殊原因。我解释了他,但他不相信。
他的观点是,如果基类破坏给出异常,派生类如何知道派生类对象将如何被破坏。
他还告诉派生类包含基类成员,为什么我们不能先调用基类破坏?
我解释说,在派生类破坏完成后,我们不能说对象被完全破坏了。
我在这儿吗?这里最好的答案是什么?
答案 0 :(得分:2)
你是对的。在采访经验丰富的C ++程序员时,我常常经常问这个问题。必须在基类之后构造派生类,以便派生类构造函数可以引用基类数据。出于同样的原因,派生类析构函数必须在基类析构函数之前运行。这是非常合乎逻辑的:我们从内到外构造,并从外部进行破坏。如果基类析构函数抛出异常,则它不能被派生类析构函数捕获。基类构造函数中的异常也不能由派生类构造函数处理。通常,不应该从析构函数中抛出异常。
答案 1 :(得分:1)
在C#对象构造中遵循以下顺序:
为什么呢?
其他语言处理初始化的方式不同,但Base->衍生建筑是典型的。
销毁是从Derived完成的 - >基
为什么?
Derived可能仍然依赖于基地在销毁期间分配的资源。
层次结构的每个级别都应负责释放该级别分配的任何资源。
回应他的具体观点:
您对订单推理的解释。如果我们假设Derived-> Base顺序是正确的,那么这就解释了为什么你仍然必须调用Base析构函数,而不是为什么Derived首先出现。
如果对订单的担忧不同,并且销毁完成了Base-> Derived,那么我们将能够在Derived析构函数完成后完全破坏对象,因为在所有级别都会发生破坏。
答案 2 :(得分:0)
重要的是要理解对象构造分阶段进行。如果你有一个从A派生的B类,你首先构造一个A,然后将A转换为B来构造B.同样,B首先将其转换为A,然后销毁A来销毁。这提供了关于对象创建和破坏的非常一致的思考方式。