簡體   English   中英

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 (**)()指向函數的指針 ),它指向虛擬表的開頭,類型為void (*[])()指向函數的指針數組 )。

第二個只是將指向對象的指針強制轉換為指向返回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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM