3 回答
TA贡献1835条经验 获得超7个赞
施工总是从基地开始
class
。如果有多个基础,class
那么构造从最左边的基础开始。(旁注:如果有virtual
继承,则给予更高的偏好)。然后构造成员字段。它们按声明的顺序初始化
最后,它
class
本身就构建了析构函数的顺序正好相反
无论初始化列表如何,呼叫顺序都是这样的:
Base
class A
的构造函数class B
将构造名为a
(类型class A
)的字段派生
class B
的构造函数
TA贡献2021条经验 获得超8个赞
假设没有虚拟/多重继承(这使事情变得复杂很多),那么规则很简单:
分配对象存储器
执行基类的构造函数,以大多数派生结束
执行成员初始化
该对象成为其类的真实实例
执行构造函数代码
需要记住的一件重要事情是,直到第4步,对象还不是其类的实例,因为它只有在构造函数的执行开始后才能获得此标题。这意味着如果在成员的构造函数期间抛出异常,则不会执行对象的析构函数,但只会破坏已构造的部分(例如成员或基类)。这也意味着如果在成员或基类的构造函数中调用对象的任何虚拟成员函数,则调用的实现将是基础实现,而不是派生实现。另一个要记住的重要事项是,初始化列表中列出的成员将按照它们在类中声明的顺序构建,
还要注意,即使在执行构造函数代码期间,this
对象已经获得了它的最终类(例如,关于虚拟分派),除非构造函数完成其执行,否则不会调用类的析构函数。只有当构造函数完成执行时,对象实例才是实例中真正的第一类公民...在此之前只是一个“想成为实例”(尽管有正确的类)。
破坏以完全相反的顺序发生:首先执行对象析构函数,然后它丢失其类(即从对象上的这一点被视为基础对象)然后所有成员以反向声明顺序销毁,最后是基类销毁过程被执行到最抽象的父级。对于构造函数,如果在基类或成员析构函数中调用对象的任何虚拟成员函数(直接或间接),则执行的实现将是父实例,因为在类析构函数完成时对象丢失了其类标题。
TA贡献1793条经验 获得超6个赞
基类始终在数据成员之前构建。数据成员按照在类中声明的顺序构造。此顺序与初始化列表无关。初始化数据成员时,它将查看参数的初始化列表,如果没有匹配则调用默认构造函数。始终以相反的顺序调用数据成员的析构函数。
- 3 回答
- 0 关注
- 397 浏览
添加回答
举报