void(**vt)()=*(void(***)())ptr;c++中虚拟表的辅助变量
void (**vt)() = *(void (***)())ptr; a helper variable for virtual table in c++
我在以下链接中发现了这种技术:http://www.codeproject.com/Tips/90875/Displaying-vtable-when-debugging
在那里,他使用了一个辅助变量
void (**vt)() = *(void (***)())ptr;
以帮助显示虚拟功能表。
但如果我把它改成
void (**vt)() = (void (**)())ptr;
它与前一个不一样。
有人能帮我解释一下这里有什么魔术吗?
为了清楚起见,我们引入一个typedef。
typedef void (**thing)();
然后第一个代码是
thing vt = *(thing*) ptr;
和第二个
thing vt = (thing) ptr;
也就是说,第一个说"把ptr当作一个指向一个东西的指针,给我它指向的东西",第二个说"当作一个东西对待ptr"
区别应该是显而易见的。
它运行的原因对于Visual C++编译器和Visual Studio调试器都非常具体。
如果调试器不知道对象的真正类型,它会显示它所知道的内容,即它是基类的实例,并且它只知道基类的vtable有多少条目。
(您在这里遗漏了一个关键部分,那就是将预期数量的表条目添加到监视窗口中的项目中。这使得调试器将内存显示为您所说的元素数组。)
因此,诀窍在于为vtable创建一个名称,并告诉调试器要从表中显示多少元素。
在许多C++实现中,虚拟表指针是对象的第一个sizeof(void (**)())
字节。当您取消引用该指针时,您将获得实际虚拟表的起始地址。这就是工作代码的含义。
cdecl
程序在这里可能有点帮助:
cdecl> explain void (***foo)()
declare foo as pointer to pointer to pointer to function returning void
cdecl> explain void (**foo)()
declare foo as pointer to pointer to function returning void
第一个代码将指向对象的指针强制转换为适当的可取消引用指针(指向函数的指针的指针,void (***)()
),然后取消引用它以获取虚拟表的起始地址,该虚拟表的类型为void (**)()
(pointer to pointer to function),其指向类型为CCD_ 5(指向函数的指针的数组)的虚拟表的开头。
第二种方法只是将指向对象的指针强制转换为指向返回void的函数的指针;变量vt中存储的地址就是对象的地址。
class Object {
public:
virtual void foo() {};
};
Object x;
// is approximately equivalent to
struct Object {
void (**_vtable)();
};
void _Object_foo(Object this) {
}
// this does not really compile, however,
// because a pointer mismatch
void (*_vtable_for_Object[])() = {
_Object_foo
};
Object y;
y._vtable = _vtable_for_Object;
因此,通过具有
Object *ptr = new Object();
// x now points to a block of memory,
// whose first bytes are void (**_vtable)()
// then
void (**vt)() = *(void (***)())ptr;
// is equivalent in our analogy to
void (**vt)() = ptr->_vtable;
// except that the C++ does not allow you to
// access the virtual table directly without
// the trickery of the former
- 在 void 函数中使用 #include 变量C++
- 是否可以将已经初始化的变量转换为 void*?
- 定义一个 void f(void) 函数,但使用来自同一范围的变量?
- 如何将变量的值安全地传递给C++方法,该方法只将void*作为参数
- 符号作为变量的值为 void:company-c-headers
- void 值没有被忽略,因为它应该是(试图将 void 分配给非 void 变量?
- 如何在 C++ 中从 void 返回函数访问变量
- 无法初始化 libsupc++ 库中类型为 'std::terminate_handler' 的变量(又名 'void (*)()')
- 带有 std::map 的模板函数给出错误:变量或字段声明为 void
- 视觉错误:变量或字段'Palindrome'在 C++ 中声明为 void
- 返回变量为 void (*)(void)
- void 函数使用相同的变量打印两个不同的答案
- 将数据读入结构中的 void* 变量
- 从 void 函数访问局部变量
- 如何通过使用void中的变量中传递信息
- 如何在 c++ 结构中的 void* 变量中调用存储函数(回调)
- 类型转换时C++ (void *) 变量和 (void *&) 变量有什么区别
- 读/写void*变量的单个字节
- 函数中的指针和void变量类型
- 如何在 C++ 中最好地将 _vector_ 对象的指针分配给 "void *" 变量?