vptr在销毁过程中会改变吗?
我正在看这篇文章,它说“进入基类析构函数后,该对象成为基类类对象,以及 C++ 的所有部分——虚拟函数、dynamic_casts 等——都是这样对待的。”这是否意味着 vptr 在销毁过程中发生了变化?这是怎么发生的?
I was looking at this article, and it says "Upon entry to the base class destructor, the object becomes a base class object, and all parts of C++—virtual functions, dynamic_casts, etc.—treat it that way." Does this mean that the vptr has changed during destruction? How does that happen?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在所有使用虚函数表的实现中(即所有当前的 C++ 实现),答案是肯定的,
vptr
更改为正在执行的析构函数的类型。原因是标准要求被析构的对象的类型是被执行的析构函数的类型。如果您具有 B、D、MD 三种类型(基础、派生、最派生)的层次结构,并且实例化并销毁
MD
类型的对象,则在执行MD::~MD 时()
对象的类型为MD
,但是当执行对基析构函数的隐式调用时,对象的运行时类型必须是D
。这是通过更新vptr
来实现的。In all implementations that use virtual function tables (i.e. all current C++ implementations) the answer is yes, the
vptr
changes to that of the type of the destructor that is being executed. The reason is that the standard requires that the type of the object being destructed is the type of the destructor being exectued.If you have a hierarchy of three types B, D, MD (base, derived, most derived) and you instantiate and destroy an object of type
MD
, then while executingMD::~MD()
the type of the object isMD
, but when the implicit call to the base destructor is executed, the runtime type of the object must beD
. This is achieved by updating thevptr
.当然,迂腐的 C++ 答案是“该标准没有提及任何有关 vtbl 或多态性如何实现的内容”。
然而,实际上来说,是的。 vtbl 在基类析构函数体开始执行之前被修改。
编辑:
以下是我如何使用 MSVC10 亲眼目睹这种情况的发生。首先是测试代码:
现在,在
Poly
dtor 的左大括号处设置一个断点。当您运行此代码时,它在左大括号处中断(就在构造函数的主体开始执行之前),您可以查看 vptr:
此外,您还可以查看
Poly
dtor 的反汇编:跨过下一行,进入析构函数的主体,然后再看一下虚拟指针:
现在,当我们从析构函数体内调用
DoTest
时,vtbl 已被修改为指向purecall_
,这会在调试器中生成运行时断言错误:The pedantic C++ answer is, of course, "The Standard doesn't say anything about vtbls or how polymorphism is implemented."
However, practically speaking, yes. The vtbl is modified before the body of the base class' destructor begins execution.
EDIT:
Here is how I used MSVC10 to see this happen for myself. First, the test code:
Now, set a breakpoint at the opening brace for the
Poly
dtor.When you run this code at it breaks on the opening brace (just before the body of the constructor begins executing), you can take a peek at the vptr:
Also, you can view the disassembly for the
Poly
dtor:Step over the next line, in to the body of the destructor, and take another peek at the vptr:
Now when we call
DoTest
from within the body of the destructor, the vtbl has already been modified to point topurecall_
, which generates a runtime assertion error in the debugger: