首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么析构函数是从派生到基础调用的最佳答案?

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

Stack Overflow用户
提问于 2011-10-14 11:55:18
回答 3查看 1.8K关注 0票数 4

我最近参加了一次面试,面试的人问我什么是建设和破坏的顺序。我解释了从基础到孩子的构建和从孩子到基础的破坏。

采访者急切地想知道从派生到基础的破坏是否有任何特殊的原因。我向他解释,但他并不信服。

他的观点是,如果基类销毁产生异常,派生类如何知道派生类对象已经被析构。

他还说派生类包含基类成员,所以为什么我们不能先调用基类销毁呢?

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

我说对了吗?这里最好的答案是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-15 01:38:44

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

派生的基本数据成员的

  1. Initialization ->
  2. 构造函数的执行基本->派生。

为什么?

  • Initialization遵循派生基类,以避免重新初始化在派生base.
  • Construction中以不同方式初始化的成员。->遵循基类->,因为派生构造函数可能依赖于基类的方法。

其他语言以不同的方式处理初始化,但Base->派生结构是典型的。

销毁是从派生的->基础完成的。

为什么?

在destruction.期间,派生的

  • 仍可使用Base分配的资源

代码语言:javascript
复制
- If the Base were destroyed first, these resources would no longer be available for the Derived.

  • 每个层级都应该负责释放该层级分配的所有资源。

代码语言:javascript
复制
- Base could not free the Derived Class's resources it has no knowledge of them.  
- Derived should also not be resposible for resources allocated by the Base  
    - In strict OOP the derived shouldn't even know the details of those resources, or in what manner they are allocated or released.

回应他的具体观点:

基础collector)中的

  • 异常
    • 异常不应在析构函数中引发(特别是在C#中,这至少会杀死垃圾collector)

  • 派生类包含基类成员
    • 对象有任何数据成员的一个实例。不是每一级的世袭。

因此,我们返回到,如果基释放了与数据成员关联的资源,则它将不再可用于派生类的use.

你对订单理由的解释。如果我们假设派生->基本顺序是正确的,这就解释了为什么你仍然必须调用基本析构函数,而不是为什么派生首先出现。

如果关于顺序的关注点是不同的,并且销毁是在Base->派生完成的,那么我们将能够认为在派生析构函数完成之后对象完全被销毁,因为销毁将在所有级别上发生。

票数 1
EN

Stack Overflow用户

发布于 2011-10-14 12:06:36

你说的完全正确。在采访有经验的C++程序员时,我经常问这个问题。派生类必须在基类之后构造,以便派生类构造函数可以引用基类数据。出于同样的原因,派生类析构函数必须在基类析构函数之前运行。这是非常合乎逻辑的:我们从内到外构建,从外到内销毁。如果基类析构函数引发异常,则派生类析构函数无法捕获该异常。基类构造函数中的异常也不能由派生类构造函数处理。一般来说,不应该从析构函数抛出异常。

票数 2
EN

Stack Overflow用户

发布于 2011-10-14 12:14:16

理解对象构造是分阶段进行的,这一点很重要。如果你有一个从A派生的类B,你可以通过首先构造A,然后把A变成B来构造B。同样,B是通过首先把它变成A,然后销毁A来销毁的。这提供了一种非常一致的思考对象创建和销毁的方式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7762866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档