2012-10-11 66 views
-6

什麼是C++類的數據結構? 它如何在裝配層面上工作?類的數據結構

IF語句是代碼行的比較+條件跳轉。

數組和字符串是數據鏈式鏈接。

+4

你到底在問什麼? – IronMan84

+2

'if'≠'jump'。至少,'if' ='compare' +'條件跳轉'。一個類通常是一個數據結構,包含數據,指向該類的虛擬方法的指針以及指向該類祖先類(如果有的話)的指針。 –

+0

C++類的數據結構是什麼? – wizztjh

回答

3

編譯器分配偏移的所有成員,包括這些上成員的所有加載/存儲操作:

struct foo { 
    uint32_t bar; 
    uint32_t baz; 

    uint32_t get_baz() { return baz; } 
}; 

uint32_t get_baz_from_foo(foo *f) { return f->baz; } 

變爲(用於簡單ARM彙編代碼):

foo__get_baz: 
    ; calling convention: this pointer in r3 
    ; load 32 bit value from r3 + 4 bytes into r0 
    ldr r0, [r3, #4]; 
    ; calling convention: return value in r0 
    ; return from subroutine 
    b lr 

get_baz_from_foo: 
    ; calling convention: first parameter in r0 
    ; load 32 bit value from r0 + 4 bytes into r0 
    ldr r0, [r0, #4] 
    ; calling convention: return value in r0 
    ; return from subroutine 
    b lr 

作爲struct編譯後各自的class佈局不變,這裏4硬編碼成指令流。

創建實例的工作方式分配內存,並從分配函數傳遞指針大家期待的指針結構:

new__foo: 
    ; two 32 bit integers need 8 bytes 
    ; calling convention: first parameter in r0 
    mov r0, #8 
    ; call allocator, which will then return to the function invoking new 
    bra malloc 

如果有一個構造

struct foo2 { 
    foo2() : bar(5), baz(7) { } 
    uint32_t bar; 
    uint32_t baz; 
    uint32_t get_baz() { return baz; } 
}; 

我們結束用一種稍微更復雜的方式來創建對象(你應該能夠弄清楚而沒有評論):

new__foo2: 
    strdb lr, ![sp] 
    mov r0, #8 
    bl malloc 
    mov r1, #5 
    str r1, [r0] 
    mov r1, #7 
    str r1, [r0, #4] 
    ldaia lr, ![sp] 
    b lr 

get_baz的實現與foo類相同。

現在,如果我構造這樣一個對象,並獲得巴茲值:

bl new__foo2 
    ; remember: the this pointer goes to r3 
    mov r3, r0 
    bl foo2__get_baz 

我結束了包含值7r0

對於virtual方法,創建隱藏的數據成員,這是一個指向的功能的表:

struct base { 
    virtual uint32_t get_baz() = 0; 
}; 

struct derived : base { 
    derived() : baz(5) { } 
    virtual uint32_t get_baz(); 
    uint32_t bar; 
    uint32_t baz; 
}; 

變得

new__derived: 
    strdb lr, ![sp] 
    mov r0, #12 
    bl malloc 
    mov r1, #5 
    str r1, [r0, #8] 
    ; get the address of the vtable 
    ldr r1, =vtable__derived 
    ; vtable typically goes to the end of the class defining it 
    ; as this is the base class, it goes before derived's data members 
    str r1, [r0] 
    ldria lr, ![sp] 
    b lr 

vtable__derived: 
    ; pointer to function 
    dw derived__get_baz 

derived__get_baz: 
    ldr r0, [r3, #8] 
    b lr 

調用此函數間接完成:

; construct normally 
    bl new__derived 
    ; here, we forget that this is a "derived" object 
    ; this pointer to r3 
    mov r3, r0 
    ; get vtable ptr 
    ldr r0, [r3] 
    ; get function ptr from vtable 
    ldr r0, [r0] 
    ; call function 
    bl r0 

這裏,r0現在是5,因爲那是構造函數存儲在那裏的。