總結:1.const重載主要是通過能否對傳入的參數進行修改為判斷的。2.const參數重載和const函數重載機制都是一樣的,因為對于const 函數重載可看做是對隐含的指針this的參數重載。3.重載是在編譯階段已經完成,對于彙編和連結來說透明的。
TAG: 彙編 const 重載
書上和網上在很多地方都對const 的重載做了一些解釋,但感覺都不是很詳細。還有很多同學在不同的地方發問關于const 重載的問題,這裡我又重新看了一下,做了一個簡單的分析也可能有不對的地方,歡迎讨論。
所 謂重載,是指允許存在多個同名函數,而這些函數的參數表不同,即函數名相同但函數的簽名不同。重載并不是面向對象程式設計的特有屬性,這是因為重載是在編譯階 段實作的,編譯器根據函數不同的參數表,對同名函數的名稱做修飾,然後這些同名函數就成了不同的函數(這一點稍後有例子)。了
Const 參數重載解析:
關于const 重載幾乎在所有c++的書中者提到過但大部分隻是一句話,例如在《C++ primer》一書中這樣描述:“可基于函數的引用形參是指向 const 對象還是指向非 const 對象,實作函數重載。将引用形參定義為 const 來重載函數是合法的,因為編譯器可以根據實參是否為 const 确定調用哪一個函數。”
但是這一段描述并沒有給出引用、指針和值傳遞前加const的實質差別是什麼。在用非const的指針,引用和值均可轉化為const的。這一點沒有太多可說明的東東。
對于函數值傳遞的情況,因為參數傳遞是通過複制實參建立一個臨時變量傳遞進函數的,函數内隻能改變臨時變量,但無法改變實參。則這個時候無論加不加 const對實參不會産生任何影響。但是在引用或指針傳遞函數調用中,因為傳進去的是一個引用或指針,這樣函數内部可以改變引用或指針所指向的變量,這時 const 才是實實在在地保護了實參所指向的變量。因為在編譯階段編譯器對調用函數的選擇是根據實參進行的,是以,隻有引用傳遞和指針傳遞可以用是否加const來 重載。
下面給出一個例子可能就更明白了:
- #include<iostream>
- class A{
- public:
- A();
- int foo(int *test);
- int foo(const int *test);
- };
- A::A(){
- }
- int A::foo(int *test){
- std::cout << *test << " A::foo(int *test)" <<std::endl;
- return 1;
- }
- int A::foo(const int *test){
- std::cout << *test << " A::foo(const int *test)" <<std::endl;
- return 1;
- }
- int main()
- {
- const int b =5;
- int c = 3;
- A a;
- a.foo(&b);
- a.foo(&c);
- return 1;
- }
輸出:
A::foo(const int *test)
A::foo(int *test)
那麼編譯器又是怎樣工作的,通過g++ -S選項将彙編代碼生成出來,通過AT&T彙編代碼可以看出一些端倪來(之是以用AT&T彙編是因為VS生成的中間代碼實在是讓人頭暈):
.file "overload.cpp"
.section .ctors,"aw",@progbits
.align 4
.long _GLOBAL__I__ZN1AC2Ev
.text
.align 2
.globl _ZN1AC2Ev
.type _ZN1AC2Ev, @function
_ZN1AC2Ev:
.LFB1399:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
popl %ebp
ret
.LFE1399:
.size _ZN1AC2Ev, .-_ZN1AC2Ev
.globl __gxx_personality_v0
.align 2
.globl _ZN1AC1Ev
.type _ZN1AC1Ev, @function
_ZN1AC1Ev:
.LFB1400:
pushl %ebp
.LCFI2:
movl %esp, %ebp
.LCFI3:
popl %ebp
ret
.LFE1400:
.size _ZN1AC1Ev, .-_ZN1AC1Ev
.align 2
.type _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB1411:
pushl %ebp
.LCFI4:
movl %esp, %ebp
.LCFI5:
subl $24, %esp
.LCFI6:
movl %eax, -4(%ebp)
movl %edx, -8(%ebp)
cmpl $1, -4(%ebp)
jne .L9
cmpl $65535, -8(%ebp)
jne .L9
movl $_ZSt8__ioinit, (%esp)
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, 8(%esp)
movl $0, 4(%esp)
movl $__tcf_0, (%esp)
call __cxa_atexit
.L9:
leave
ret
.LFE1411:
.size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
.align 2
.type _GLOBAL__I__ZN1AC2Ev, @function
_GLOBAL__I__ZN1AC2Ev:
.LFB1413:
pushl %ebp
.LCFI7:
movl %esp, %ebp
.LCFI8:
subl $8, %esp
.LCFI9:
movl $65535, %edx
movl $1, %eax
call _Z41__static_initialization_and_destruction_0ii
leave
ret
.LFE1413:
.size _GLOBAL__I__ZN1AC2Ev, .-_GLOBAL__I__ZN1AC2Ev
.align 2
.type __tcf_0, @function
__tcf_0:
.LFB1412:
pushl %ebp
.LCFI10:
movl %esp, %ebp
.LCFI11:
subl $8, %esp
.LCFI12:
movl $_ZSt8__ioinit, (%esp)
call _ZNSt8ios_base4InitD1Ev
leave
ret
.LFE1412:
.size __tcf_0, .-__tcf_0
.section .rodata
.LC0:
.string " A::foo(const int *test)"
.text
.align 2
.globl _ZN1A3fooEPKi
.type _ZN1A3fooEPKi, @function
_ZN1A3fooEPKi:
.LFB1402:
pushl %ebp
.LCFI13:
movl %esp, %ebp
.LCFI14:
subl $8, %esp
.LCFI15:
movl 12(%ebp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp)
call _ZNSolsEi
movl $.LC0, 4(%esp)
movl %eax, (%esp)
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
movl $1, %eax
leave
ret
.LFE1402:
.size _ZN1A3fooEPKi, .-_ZN1A3fooEPKi
.section .rodata
.LC1:
.string " A::foo(int *test)"
.text
.align 2
.globl _ZN1A3fooEPi
.type _ZN1A3fooEPi, @function
_ZN1A3fooEPi:
.LFB1401:
pushl %ebp
.LCFI16:
movl %esp, %ebp
.LCFI17:
subl $8, %esp
.LCFI18:
movl 12(%ebp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp)
call _ZNSolsEi
movl $.LC1, 4(%esp)
movl %eax, (%esp)
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
movl $1, %eax
leave
ret
.LFE1401:
.size _ZN1A3fooEPi, .-_ZN1A3fooEPi
.align 2
.globl main
.type main, @function
main:
.LFB1403:
leal 4(%esp), %ecx
.LCFI19:
andl $-16, %esp
pushl -4(%ecx)
.LCFI20:
pushl %ebp
.LCFI21:
movl %esp, %ebp
.LCFI22:
pushl %ecx
.LCFI23:
subl $36, %esp
.LCFI24:
movl $5, -8(%ebp)
movl $3, -12(%ebp)
leal -13(%ebp), %eax
movl %eax, (%esp)
call _ZN1AC1Ev
leal -8(%ebp), %eax
movl %eax, 4(%esp)
leal -13(%ebp), %eax
movl %eax, (%esp)
call _ZN1A3fooEPKi
leal -12(%ebp), %eax
movl %eax, 4(%esp)
leal -13(%ebp), %eax
movl %eax, (%esp)
call _ZN1A3fooEPi
movl $1, %eax
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.LFE1403:
.size main, .-main
.local _ZSt8__ioinit
.comm _ZSt8__ioinit,1,1
.weakref _Z20__gthrw_pthread_oncePiPFvvE,pthread_once
.weakref _Z27__gthrw_pthread_getspecificj,pthread_getspecific
.weakref _Z27__gthrw_pthread_setspecificjPKv,pthread_setspecific
.weakref _Z22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
.weakref _Z22__gthrw_pthread_cancelm,pthread_cancel
.weakref _Z26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
.weakref _Z29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
.weakref _Z28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
.weakref _Z26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
.weakref _Z26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
.weakref _Z26__gthrw_pthread_key_deletej,pthread_key_delete
.weakref _Z30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
.weakref _Z33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
.weakref _Z33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zP"
.uleb128 0x1
.sleb128 -4
.byte 0x8
.uleb128 0x5
.byte 0x0
.long __gxx_personality_v0
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x88
.uleb128 0x1
.align 4
.LECIE1:
.LSFDE5:
.long .LEFDE5-.LASFDE5
.LASFDE5:
.long .LASFDE5-.Lframe1
.long .LFB1411
.long .LFE1411-.LFB1411
.uleb128 0x0
.byte 0x4
.long .LCFI4-.LFB1411
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI5-.LCFI4
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE5:
.LSFDE7:
.long .LEFDE7-.LASFDE7
.LASFDE7:
.long .LASFDE7-.Lframe1
.long .LFB1413
.long .LFE1413-.LFB1413
.uleb128 0x0
.byte 0x4
.long .LCFI7-.LFB1413
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI8-.LCFI7
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE7:
.LSFDE9:
.long .LEFDE9-.LASFDE9
.LASFDE9:
.long .LASFDE9-.Lframe1
.long .LFB1412
.long .LFE1412-.LFB1412
.uleb128 0x0
.byte 0x4
.long .LCFI10-.LFB1412
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI11-.LCFI10
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE9:
.LSFDE11:
.long .LEFDE11-.LASFDE11
.LASFDE11:
.long .LASFDE11-.Lframe1
.long .LFB1402
.long .LFE1402-.LFB1402
.uleb128 0x0
.byte 0x4
.long .LCFI13-.LFB1402
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI14-.LCFI13
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE11:
.LSFDE13:
.long .LEFDE13-.LASFDE13
.LASFDE13:
.long .LASFDE13-.Lframe1
.long .LFB1401
.long .LFE1401-.LFB1401
.uleb128 0x0
.byte 0x4
.long .LCFI16-.LFB1401
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI17-.LCFI16
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE13:
.LSFDE15:
.long .LEFDE15-.LASFDE15
.LASFDE15:
.long .LASFDE15-.Lframe1
.long .LFB1403
.long .LFE1403-.LFB1403
.uleb128 0x0
.byte 0x4
.long .LCFI19-.LFB1403
.byte 0xc
.uleb128 0x1
.uleb128 0x0
.byte 0x9
.uleb128 0x4
.uleb128 0x1
.byte 0x4
.long .LCFI20-.LCFI19
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x4
.long .LCFI21-.LCFI20
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI22-.LCFI21
.byte 0xd
.uleb128 0x5
.byte 0x4
.long .LCFI23-.LCFI22
.byte 0x84
.uleb128 0x3
.align 4
.LEFDE15:
.ident "GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)"
.section .note.GNU-stack,"",@progbits
如上面的代碼函數:
int foo(int *test);和int foo(const int *test);
分别被編譯器生成名為:_ZN1A3fooEPKi和_ZN1A3fooEPi(這兩個名字會因為編譯器的不同而不同,名字隻是一個區分的 符号而已不用深究,隻用知道重載的函數經過編譯器的處理函數名字已經發生了變化。是以對于後面的彙編和連結工作就不存在重載的問題了。)這裡也同時說明對 重載來說在編譯階段已經完成。
對于a.foo(&b);因為變量b有const修飾是以就調用了int foo(const int *test);對于a.foo(&c);調用int foo(int *test);因為這個是精确比對的。但是如果沒有定義int foo(const int *test);則在代碼24行會出現編譯錯誤。反過來如果沒有定義函數:int foo(int *test);如下:
- #include<iostream>
- class A{
- public:
- A();
- // int foo(int *test);
- int foo(const int *test);
- };
- A::A(){
- }
- /*int A::foo(int *test){
- std::cout << *test << " A::foo(int *test)" <<std::endl;
- return 1;
- }
- */
- int A::foo(const int *test){
- std::cout << *test << " A::foo(const int *test)" <<std::endl;
- return 1;
- }
- int main()
- {
- const int b =5;
- int c = 3;
- A a;
- a.foo(&b);
- a.foo(&c);
- return 1;
- }
則輸出結果為:
5 A::foo(const int *test)
3 A::foo(const int *test)
原因c++ primer上講的很清楚:“We can use a nonconst object to initializer either aconst or nonconst reference. However, initializing aconst reference to a nonconst object requires a conversion, whereas initializing a nonconst parameter is an exact match.”
const 成員函數重載的解析:
const 成員函數重載的解析和const參數重載解析的原理可以說是一樣的。之是以這樣說是因為const成員函數的解析可被看做是對函數this參數用const來修飾的過程。例如下面代碼:
- #include<iostream>
- class A{
- public:
- A();
- int foo(int *test); //可看做:int foo(A *this,int *test);
- int foo(int *test) const;//可看做:int foo(const A *this,int *test);
- };
- A::A(){
- }
- int A::foo(int *test){
- std::cout << *test << "foo" <<std::endl;
- return 1;
- }
- int A::foo(int *test) const {
- std::cout << *test << "foo const" <<std::endl;
- return 1;
- }
- int main()
- {
- int b = 5;
- const A a;
- a.foo(&b);
- return 1;
- }
生成彙編為:
.file "overload1.cpp"
.section .ctors,"aw",@progbits
.align 4
.long _GLOBAL__I__ZN1AC2Ev
.text
.align 2
.globl _ZN1AC2Ev
.type _ZN1AC2Ev, @function
_ZN1AC2Ev:
.LFB1399:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
popl %ebp
ret
.LFE1399:
.size _ZN1AC2Ev, .-_ZN1AC2Ev
.globl __gxx_personality_v0
.align 2
.globl _ZN1AC1Ev
.type _ZN1AC1Ev, @function
_ZN1AC1Ev:
.LFB1400:
pushl %ebp
.LCFI2:
movl %esp, %ebp
.LCFI3:
popl %ebp
ret
.LFE1400:
.size _ZN1AC1Ev, .-_ZN1AC1Ev
.align 2
.type _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB1411:
pushl %ebp
.LCFI4:
movl %esp, %ebp
.LCFI5:
subl $24, %esp
.LCFI6:
movl %eax, -4(%ebp)
movl %edx, -8(%ebp)
cmpl $1, -4(%ebp)
jne .L9
cmpl $65535, -8(%ebp)
jne .L9
movl $_ZSt8__ioinit, (%esp)
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, 8(%esp)
movl $0, 4(%esp)
movl $__tcf_0, (%esp)
call __cxa_atexit
.L9:
leave
ret
.LFE1411:
.size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
.align 2
.type _GLOBAL__I__ZN1AC2Ev, @function
_GLOBAL__I__ZN1AC2Ev:
.LFB1413:
pushl %ebp
.LCFI7:
movl %esp, %ebp
.LCFI8:
subl $8, %esp
.LCFI9:
movl $65535, %edx
movl $1, %eax
call _Z41__static_initialization_and_destruction_0ii
leave
ret
.LFE1413:
.size _GLOBAL__I__ZN1AC2Ev, .-_GLOBAL__I__ZN1AC2Ev
.align 2
.type __tcf_0, @function
__tcf_0:
.LFB1412:
pushl %ebp
.LCFI10:
movl %esp, %ebp
.LCFI11:
subl $8, %esp
.LCFI12:
movl $_ZSt8__ioinit, (%esp)
call _ZNSt8ios_base4InitD1Ev
leave
ret
.LFE1412:
.size __tcf_0, .-__tcf_0
.section .rodata
.LC0:
.string "foo const"
.text
.align 2
.globl _ZNK1A3fooEPi
.type _ZNK1A3fooEPi, @function
_ZNK1A3fooEPi:
.LFB1402:
pushl %ebp
.LCFI13:
movl %esp, %ebp
.LCFI14:
subl $8, %esp
.LCFI15:
movl 12(%ebp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp)
call _ZNSolsEi
movl $.LC0, 4(%esp)
movl %eax, (%esp)
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
movl $1, %eax
leave
ret
.LFE1402:
.size _ZNK1A3fooEPi, .-_ZNK1A3fooEPi
.align 2
.globl main
.type main, @function
main:
.LFB1403:
leal 4(%esp), %ecx
.LCFI16:
andl $-16, %esp
pushl -4(%ecx)
.LCFI17:
pushl %ebp
.LCFI18:
movl %esp, %ebp
.LCFI19:
pushl %ecx
.LCFI20:
subl $36, %esp
.LCFI21:
movl $5, -8(%ebp)
leal -9(%ebp), %eax
movl %eax, (%esp)
call _ZN1AC1Ev
leal -8(%ebp), %eax
movl %eax, 4(%esp)
leal -9(%ebp), %eax
movl %eax, (%esp)
call _ZNK1A3fooEPi
movl $1, %eax
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.LFE1403:
.size main, .-main
.section .rodata
.LC1:
.string "foo"
.text
.align 2
.globl _ZN1A3fooEPi
.type _ZN1A3fooEPi, @function
_ZN1A3fooEPi:
.LFB1401:
pushl %ebp
.LCFI22:
movl %esp, %ebp
.LCFI23:
subl $8, %esp
.LCFI24:
movl 12(%ebp), %eax
movl (%eax), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp)
call _ZNSolsEi
movl $.LC1, 4(%esp)
movl %eax, (%esp)
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
movl $1, %eax
leave
ret
.LFE1401:
.size _ZN1A3fooEPi, .-_ZN1A3fooEPi
.local _ZSt8__ioinit
.comm _ZSt8__ioinit,1,1
.weakref _Z20__gthrw_pthread_oncePiPFvvE,pthread_once
.weakref _Z27__gthrw_pthread_getspecificj,pthread_getspecific
.weakref _Z27__gthrw_pthread_setspecificjPKv,pthread_setspecific
.weakref _Z22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
.weakref _Z22__gthrw_pthread_cancelm,pthread_cancel
.weakref _Z26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
.weakref _Z29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
.weakref _Z28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
.weakref _Z26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
.weakref _Z26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
.weakref _Z26__gthrw_pthread_key_deletej,pthread_key_delete
.weakref _Z30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
.weakref _Z33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
.weakref _Z33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zP"
.uleb128 0x1
.sleb128 -4
.byte 0x8
.uleb128 0x5
.byte 0x0
.long __gxx_personality_v0
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x88
.uleb128 0x1
.align 4
.LECIE1:
.LSFDE5:
.long .LEFDE5-.LASFDE5
.LASFDE5:
.long .LASFDE5-.Lframe1
.long .LFB1411
.long .LFE1411-.LFB1411
.uleb128 0x0
.byte 0x4
.long .LCFI4-.LFB1411
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI5-.LCFI4
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE5:
.LSFDE7:
.long .LEFDE7-.LASFDE7
.LASFDE7:
.long .LASFDE7-.Lframe1
.long .LFB1413
.long .LFE1413-.LFB1413
.uleb128 0x0
.byte 0x4
.long .LCFI7-.LFB1413
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI8-.LCFI7
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE7:
.LSFDE9:
.long .LEFDE9-.LASFDE9
.LASFDE9:
.long .LASFDE9-.Lframe1
.long .LFB1412
.long .LFE1412-.LFB1412
.uleb128 0x0
.byte 0x4
.long .LCFI10-.LFB1412
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI11-.LCFI10
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE9:
.LSFDE11:
.long .LEFDE11-.LASFDE11
.LASFDE11:
.long .LASFDE11-.Lframe1
.long .LFB1402
.long .LFE1402-.LFB1402
.uleb128 0x0
.byte 0x4
.long .LCFI13-.LFB1402
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI14-.LCFI13
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE11:
.LSFDE13:
.long .LEFDE13-.LASFDE13
.LASFDE13:
.long .LASFDE13-.Lframe1
.long .LFB1403
.long .LFE1403-.LFB1403
.uleb128 0x0
.byte 0x4
.long .LCFI16-.LFB1403
.byte 0xc
.uleb128 0x1
.uleb128 0x0
.byte 0x9
.uleb128 0x4
.uleb128 0x1
.byte 0x4
.long .LCFI17-.LCFI16
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x4
.long .LCFI18-.LCFI17
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI19-.LCFI18
.byte 0xd
.uleb128 0x5
.byte 0x4
.long .LCFI20-.LCFI19
.byte 0x84
.uleb128 0x3
.align 4
.LEFDE13:
.LSFDE15:
.long .LEFDE15-.LASFDE15
.LASFDE15:
.long .LASFDE15-.Lframe1
.long .LFB1401
.long .LFE1401-.LFB1401
.uleb128 0x0
.byte 0x4
.long .LCFI22-.LFB1401
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI23-.LCFI22
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE15:
.ident "GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)"
.section .note.GNU-stack,"",@progbits
上面可以看到編譯階段的調用也是通過對重載函數的别名來實作的。
總結:
1.const重載主要是通過能否對傳入的參數進行修改為判斷的。
2.const參數重載和const函數重載機制都是一樣的,因為對于const 函數重載可看做是對隐含的指針this的參數重載。
3.重載是在編譯階段已經完成,對于彙編和連結來說透明的。
文章轉載自:羅索實驗室 [http://www.rosoo.net/a/201203/15893.html]