2011-11-20 63 views
3

有這樣的C++代碼:成員函數如何知道它是爲特定對象調用的?

#include <iostream> 

class MojaKlasa{ 
public: 
    int z; 
    void fun(){ std::cout << this;}; 
}; 

int main() 
{ 
    MojaKlasa a; 
    a.z = 2; 
    a.fun(); 
    return 0; 
} 

而且coresponding彙編代碼:

.file "prog50.cpp" 
    .local _ZStL8__ioinit 
    .comm _ZStL8__ioinit,1,1 
    .section .text._ZN9MojaKlasa3funEv,"axG",@progbits,_ZN9MojaKlasa3funEv,comdat 
    .align 2 
    .weak _ZN9MojaKlasa3funEv 
    .type _ZN9MojaKlasa3funEv, @function 
_ZN9MojaKlasa3funEv: 
.LFB957: 
    .cfi_startproc 
    .cfi_personality 0x0,__gxx_personality_v0 
    pushl %ebp 
    .cfi_def_cfa_offset 8 
    movl %esp, %ebp 
    .cfi_offset 5, -8 
    .cfi_def_cfa_register 5 
    subl $24, %esp 
    movl 8(%ebp), %eax 
    movl %eax, 4(%esp) 
    movl $_ZSt4cout, (%esp) 
    call _ZNSolsEPKv 
    leave 
    ret 
    .cfi_endproc 
.LFE957: 
    .size _ZN9MojaKlasa3funEv, .-_ZN9MojaKlasa3funEv 
    .text 
.globl main 
    .type main, @function 
main: 
.LFB958: 
    .cfi_startproc 
    .cfi_personality 0x0,__gxx_personality_v0 
    pushl %ebp 
    .cfi_def_cfa_offset 8 
    movl %esp, %ebp 
    .cfi_offset 5, -8 
    .cfi_def_cfa_register 5 
    andl $-16, %esp 
    subl $32, %esp 
    movl $2, 28(%esp)  # a.z = 2; 
    leal 28(%esp), %eax 
    movl %eax, (%esp) 
    call _ZN9MojaKlasa3funEv # a.fun(); 
    movl $0, %eax 
    leave 
    ret 
    .cfi_endproc 
.LFE958: 
    .size main, .-main 
    .type _Z41__static_initialization_and_destruction_0ii, @function 
_Z41__static_initialization_and_destruction_0ii: 
.LFB960: 
    .cfi_startproc 
    .cfi_personality 0x0,__gxx_personality_v0 
    pushl %ebp 
    .cfi_def_cfa_offset 8 
    movl %esp, %ebp 
    .cfi_offset 5, -8 
    .cfi_def_cfa_register 5 
    subl $24, %esp 
    cmpl $1, 8(%ebp) 
    jne .L7 
    cmpl $65535, 12(%ebp) 
    jne .L7 
    movl $_ZStL8__ioinit, (%esp) 
    call _ZNSt8ios_base4InitC1Ev 
    movl $_ZNSt8ios_base4InitD1Ev, %eax 
    movl $__dso_handle, 8(%esp) 
    movl $_ZStL8__ioinit, 4(%esp) 
    movl %eax, (%esp) 
    call __cxa_atexit 
.L7: 
    leave 
    ret 
    .cfi_endproc 
.LFE960: 
    .size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii 
    .type _GLOBAL__I_main, @function 
_GLOBAL__I_main: 
.LFB961: 
    .cfi_startproc 
    .cfi_personality 0x0,__gxx_personality_v0 
    pushl %ebp 
    .cfi_def_cfa_offset 8 
    movl %esp, %ebp 
    .cfi_offset 5, -8 
    .cfi_def_cfa_register 5 
    subl $24, %esp 
    movl $65535, 4(%esp) 
    movl $1, (%esp) 
    call _Z41__static_initialization_and_destruction_0ii 
    leave 
    ret 
    .cfi_endproc 
.LFE961: 
    .size _GLOBAL__I_main, .-_GLOBAL__I_main 
    .section .ctors,"aw",@progbits 
    .align 4 
    .long _GLOBAL__I_main 
    .weakref _ZL20__gthrw_pthread_oncePiPFvvE,pthread_once 
    .weakref _ZL27__gthrw_pthread_getspecificj,pthread_getspecific 
    .weakref _ZL27__gthrw_pthread_setspecificjPKv,pthread_setspecific 
    .weakref _ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create 
    .weakref _ZL20__gthrw_pthread_joinmPPv,pthread_join 
    .weakref _ZL21__gthrw_pthread_equalmm,pthread_equal 
    .weakref _ZL20__gthrw_pthread_selfv,pthread_self 
    .weakref _ZL22__gthrw_pthread_detachm,pthread_detach 
    .weakref _ZL22__gthrw_pthread_cancelm,pthread_cancel 
    .weakref _ZL19__gthrw_sched_yieldv,sched_yield 
    .weakref _ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock 
    .weakref _ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock 
    .weakref _ZL31__gthrw_pthread_mutex_timedlockP15pthread_mutex_tPK8timespec,pthread_mutex_timedlock 
    .weakref _ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock 
    .weakref _ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init 
    .weakref _ZL29__gthrw_pthread_mutex_destroyP15pthread_mutex_t,pthread_mutex_destroy 
    .weakref _ZL30__gthrw_pthread_cond_broadcastP14pthread_cond_t,pthread_cond_broadcast 
    .weakref _ZL27__gthrw_pthread_cond_signalP14pthread_cond_t,pthread_cond_signal 
    .weakref _ZL25__gthrw_pthread_cond_waitP14pthread_cond_tP15pthread_mutex_t,pthread_cond_wait 
    .weakref _ZL30__gthrw_pthread_cond_timedwaitP14pthread_cond_tP15pthread_mutex_tPK8timespec,pthread_cond_timedwait 
    .weakref _ZL28__gthrw_pthread_cond_destroyP14pthread_cond_t,pthread_cond_destroy 
    .weakref _ZL26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create 
    .weakref _ZL26__gthrw_pthread_key_deletej,pthread_key_delete 
    .weakref _ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init 
    .weakref _ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype 
    .weakref _ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy 
    .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" 
    .section .note.GNU-stack,"",@progbits 
  1. 看來,功能樂趣()類MojaKlasa的被翻譯爲正常的常規功能。功能如何知道它被稱爲特定對象,例如a.fun() - >致電fun()對象a

  2. 第二個問題是,類MojaKlasa的默認構造函數和析構函數在哪裏?據說C++自動爲類創建構造函數和析構函數,但似乎並未將其中的一個包含在彙編代碼中。

+1

也許[最近這次我的答案](HTTP://計算器。com/questions/8196833/internal-representation-of-objects/8198062#8198062)也很有用。 –

回答

6

函數如何知道它是爲特定對象調用的,例如a.fun() -> call fun() for object a

指向對象this的指針作爲第一個隱藏參數隱式傳遞給成員函數。

其中默認的構造函數和析構函數爲class MojaKlasa

C++原理是:您只支付你使用的費用。
除非你的代碼明確需要一個默認的無參數構造函數,否則編譯器不會生成它。

1

根本看不到彙編代碼,你應該知道成員函數有一個隱藏的參數傳遞。這稱爲this指針。因此調用擁有自己的這個指針,並且專門爲該對象調用每個函數。

關於你的第二個問題,你可以放心,默認的構造函數和析構函數是生成的,儘管沒有專業知識的gcc編譯器的內部,它真的很難找到它在哪裏或如何調用。

我試過這與Visual Studio 2010,我也無法找到這個信息的dissasembly。

0

總之,成員函數有一個隱藏參數:

void Class::func(int i); // Becomes... 
void func(Class const* this, int i); 

當調用函數,obj.func(7),它被「轉換」到func(&obj, 7)。這幾乎是它的傑作。

在C++中,這是一個隱藏/隱式參數,但是有一些語言要求這是一個明確的參數。在Python中,例如,你會寫這個(self在Python是相當於this在C++中):

class Class: 
    def func(self, i): 
     ... 
相關問題