使用虚拟破坏顺序
有人可以帮助我使用虚拟函数时的破坏顺序吗?是从基类开始,然后是派生类吗?
Can some one please help what the order of destruction is when I am using virtual functions. Does it start with the base class and then derived class?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
由于我没有看到虚拟函数如何更改任何对象的销毁顺序,因此我假设您指的是虚拟继承中的基类和数据成员的销毁顺序继承 场景。
子对象构造
破坏与构造完全相反,所以你只需要记住上面的内容即可。
然而,上述四个规则是按这个顺序排列的,因为这是有道理的,如果你理解为什么这个顺序有意义,你甚至不必记住这四个规则,而是可以从你的理解中推断出它们(就像我刚才所做的那样)。因此,让我们检查一下该顺序:
Since I don't see how virtual function change any objects' destruction order, I assume you're referring to the order of destruction for base classes and data members in a virtual inheritance scenario.
Sub-objects are constructed
Destruction is simply the opposite of construction, so you only need to memorize the above.
However, the above four rules are in that order because that makes sense, and if you understand why this order makes sense, you will not even have to memorize those four rules, but can infer them from your understanding (as I just did). So let's examine that order:
假设您已正确将析构函数声明为虚拟的。
然后以与构造完全相反的顺序进行破坏。
一般来说,这将是:
A) 从最派生的类开始。
B) 递归地重复以下操作。
1) 执行析构函数代码。
2)执行每个成员的析构函数(与创建的顺序相反)
3)执行父类的析构函数。 (如果有多个以相反的创建顺序)
如果您使用虚拟继承,那么情况会略有不同,因为基类构造的顺序与正常情况不同。 但是破坏的顺序总是与构造的顺序相反。
Assuming you have correctly declared your destructor as virtual.
Then destruction is done in the exact opposite order of construction.
In General this will be:
A) Start in the most derived class.
B) Repeat the following recursively.
1) Execute the destructor code.
2) Execute the destructor of each member (in reverse order of creation)
3) Execute the destructor of the parent class. (if more than one in reverse order of creation)
If you use virtual inheritance though then things are slightly different as the order of base class construction is not the same as normal. BUT The order of destruction is ALWAYS the reverse of the order of construction.
破坏顺序是构造顺序的倒序。我最近制作了一个小工具来显示任何层次结构的构造顺序。看这里:
在图中,编号较小的节点第一个被构造,最后被破坏。
The destruction order is the construction order backwards. I've recently made a small tool to display the construction order for any hierarchy. Look here:
In the diagrams, the nodes with the smaller numbers are constructed first and destructed last.
第 12.6.2/5 节:
Section 12.6.2/5:
这与构造函数相反。故先推导。
It is the opposite way as the constructors. So derived first.
从下到上的破坏顺序。 (从派生到基础)
请参阅 c++ 常见问题解答第 25 节
Order of destructions if from the bottom up. (from derived to base)
See the c++ faq section 25
虚拟函数对销毁顺序没有影响,而虚拟基类则不同。
如果没有虚拟基类,派生类总是在其基类之前被销毁;这是它们构建的相反顺序。
对于最派生的类,首先构造虚拟基类,然后再构造其他基类和最派生的类本身。破坏以相反的顺序发生。这意味着虚拟基可能在从其虚拟派生的类之后被销毁,如果该类不是被销毁的最派生类。对于直接基类来说,这种情况永远不会发生。
Virtual functions make no difference to the order of destruction, virtual base classes, on the other hand, do.
Without virtual base classes, derived classes are always destroyed before their base classes; this is the reverse order in which they are constructed.
For the most derived class, virtual base classes are constructed first, before other base classes and before the most derived class itself. Destruction happens in the reverse order. This means that a virtual base may be destroyed after a class that derives virtually from it, if that class is not the most derived class being destroyed. This can never happen for direct base classes.
首先是派生的,然后是基数。非虚拟案例没有区别。
附加说明。当您有继承和虚拟方法时,您必须将析构函数声明为虚拟,否则在删除时可能会出现未定义的行为。
例如,假设 Derived 是从 Base 派生的,并且您使用以下行分配 Derived:
如果这种情况发生在您的代码中,并且 Base 没有虚拟析构函数,则结果行为是未定义的。通常,只会调用 Base 的析构函数。 Derived 的析构函数不会被调用,因为您正在对 Base 指针调用 delete。但是,程序可能会崩溃。一旦你处于未定义行为的领域,所有的赌注都会被取消,你正在运行的代码注定会失败。为了防止混乱,Base 析构函数必须是虚拟的。
First the derived, then the base. No difference wrt the non-virtual cases.
Additional note. When you have inheritance and virtual methods, you have to declare destructors as virtual, otherwise you can have undefined behavior at deletion.
Example, suppose Derived is derived from Base, and you allocate Derived with the following line:
If this case occurs in your code, and Base has no virtual destructor, the resulting behavior is undefined. Typically, only the destructor of Base will be called. The destructor of Derived will not be called, because you are calling delete on a Base pointer. However, the program might crash instead. Once you are in the realm of undefined behavior, all bets are off and your running code is doomed. To prevent chaos the Base destructor must be virtual.