C ++:帮助理解这行代码

时间:2014-12-06 11:56:15

标签: c++ visual-studio vtable vptr

我一直想找一种通过指针直接访问vtable的方法,并发现了这篇文章:http://www.codeproject.com/Tips/90875/Displaying-vtable-when-debugging

它工作正常,我可以通过vtable条目调用函数。 但是我无法理解这一系列的deo:

void (**vt)() = *(void (***)())ptr;

ptr是指向对象的指针。我怎样才能解读这一行以及vt如何获得vtable地址?

谢谢。

2 个答案:

答案 0 :(得分:2)

对象中_vtable的实际位置取决于编译器。代码假定_vtable地址首先存储在对象中(所有现代编译器似乎都这样做)。此外,每个类只有一个vtable,它存储在一个位置。因此,每个实例都有一个指向函数指针数组的地址。

基本上,您创建一个名为vt的变量,这是一个指向函数的指针数组,这些函数返回void并且不带参数。然后使用在对象的第一个成员(vtable的地址)中找到的内容初始化此变量。

(void (***)())ptr

表示将前4个(32位机器)或8个(64位机器)转换为指向返回void并且不带参数的函数指针数组的指针。

*(void (***)())ptr

返回那些4或8字节的内容,即vtable的地址。

答案 1 :(得分:1)

void (**vt)()
vt是指向某个函数的指针。此函数返回void并且不带参数 void (***)()
指向指向这种函数的指针的指针(即,一个指针级别多于上面的指针级别)。

首先,你将ptr转换为这样一个三级指针功能 然后,你得到它指向的东西(使用单*),这是一个两级指针到函数,即。同一类型变量vt。这意味着你可以将它分配给vt,这就是这条线的作用。

为什么?

指向void-no-param函数的单个函数指针可以存储在这样的变量x:void(*x)()中。并不完全相关,如果你想将一些数组传递给一个函数,你传递一个指针。 IE浏览器。这足以将数组地址存储在一个指针中以访问整个数组(如果长度已知) 这意味着void(**vt)()可以存储(函数指针数组)的地址 vtable不是别的,只是一个函数指针数组。

如果你有一个Car类,它有一些变量,比如颜色和vtable,它使用eg。每个对象200字节。指向汽车的指针就像是指向200字节数组的指针,如果在代码中访问颜色,编译器会查找该颜色,例如。字节133并生成对它的访问。

vtable在此对象中的位置是实现定义的,但通常在开头。如果你有一个指向汽车的指针,它是一个指向200字节数组的指针,首先分成一些fucntion指针,然后分成一些其他数据......

=> vtable,即。一系列函数指针,从汽车的起始地址开始 =>如果你将汽车指针投射到指向vtable的指针,即。指向“函数指针数组”的指针,即。指向“指向函数的指针”的指针,并且你有vtable数组。