c++ 基础之函数重载分析

296 阅读2分钟

c++ 重载分析

一、
double test(int a);
double test(double b);
double test(int a, double b);

调用:

test(1) ;
test(1.1);
test(1, 1.1);

打开反汇编:可以看到调用函数地址不同

00E5180E mov esi,esp
00E51810 push offset std::endl<char,std::char_traits > (0E51064h)
00E51815 push 1
00E51817 call test (0E51357h)
00E5181C add esp,4
00E5181F mov edi,esp
00E51821 sub esp,8
00E51824 fstp qword ptr [esp]
00E51827 mov ecx,dword ptr [imp?cout@std@@3V?basicostream@DU?basic_ostream@DU?char_traits@D@std@@@1@A (0E5A0A8h)]
00E5182D call dword ptr [__imp_std::basic_ostream<char,std::char_traits >::operator<< (0E5A0A0h)]
00E51833 cmp edi,esp
00E51835 call __RTC_CheckEsp (0E5111Dh)
00E5183A mov ecx,eax
00E5183C call dword ptr [__imp_std::basic_ostream<char,std::char_traits >::operator<< (0E5A0A4h)]
00E51842 cmp esi,esp
00E51844 call __RTC_CheckEsp (0E5111Dh)
cout << test(1.1) << endl; 00E51849 mov esi,esp
00E5184B push offset std::endl<char,std::char_traits > (0E51064h)
00E51850 sub esp,8
00E51853 movsd xmm0,mmword ptr [__real@3ff199999999999a (0E56B30h)]
00E5185B movsd mmword ptr [esp],xmm0
00E51860 call test (0E51352h)
00E51865 add esp,8
00E51868 mov edi,esp
00E5186A sub esp,8
00E5186D fstp qword ptr [esp]
00E51870 mov ecx,dword ptr [imp?cout@std@@3V?basicostream@DU?basic_ostream@DU?char_traits@D@std@@@1@A (0E5A0A8h)]
00E51876 call dword ptr [__imp_std::basic_ostream<char,std::char_traits >::operator<< (0E5A0A0h)]
00E5187C cmp edi,esp
00E5187E call __RTC_CheckEsp (0E5111Dh)
00E51883 mov ecx,eax
00E51885 call dword ptr [__imp_std::basic_ostream<char,std::char_traits >::operator<< (0E5A0A4h)]
00E5188B cmp esi,esp
00E5188D call __RTC_CheckEsp (0E5111Dh)
cout << test(1, 1.1) << endl; 00E51892 mov esi,esp
00E51894 push offset std::endl<char,std::char_traits > (0E51064h)
00E51899 sub esp,8
00E5189C movsd xmm0,mmword ptr [__real@3ff199999999999a (0E56B30h)]
00E518A4 movsd mmword ptr [esp],xmm0
00E518A9 push 1
00E518AB call test (0E5117Ch)
00E518B0 add esp,0Ch
00E518B3 mov edi,esp
00E518B5 sub esp,8
00E518B8 fstp qword ptr [esp]
00E518BB mov ecx,dword ptr [imp?cout@std@@3V?basicostream@DU?basic_ostream@DU?char_traits@D@std@@@1@A (0E5A0A8h)]
00E518C1 call dword ptr [__imp_std::basic_ostream<char,std::char_traits >::operator<< (0E5A0A0h)]
00E518C7 cmp edi,esp
00E518C9 call __RTC_CheckEsp (0E5111Dh)
00E518CE mov ecx,eax
cout << test(1, 1.1) << endl; 00E518D0 call dword ptr [__imp_std::basic_ostream<char,std::char_traits >::operator<< (0E5A0A4h)]
00E518D6 cmp esi,esp
00E518D8 call __RTC_CheckEsp (0E5111Dh)

对应的函数地址:

test (0E51357h)

test (0E51352h)

test (0E5117Ch)

二、

​ 工程下打开obj文件,查询“test”,得到:

​ ?test@@YANH@Z ?test@@YANN@Z ?test@@YANHN@Z

使用工具undname.exe

D:\Apps\IDE\VS2015\VC\bin>undname.exe ?test@@YANH@Z Undecoration of :- "?test@@YANH@Z" is :- "double __cdecl test(int)"

D:\Apps\IDE\VS2015\VC\bin>undname.exe ?test@@YANN@Z Undecoration of :- "?test@@YANN@Z" is :- "double __cdecl test(double)"

D:\Apps\IDE\VS2015\VC\bin>undname.exe ?test@@YANHN@Z Undecoration of :- "?test@@YANHN@Z" is :- "double __cdecl test(int,double)"

三、

默认参数带来的问题

double test(int a);
double test(double b);
double test(int a, double b = 1.1);

调用:

test(1); // 编译报错,这里编译器不知道call哪一个

》》如何调用:函数指针

double(*p)(int); // 返回值(*函数指针)(参数)
p = test;
cout << (*p)(1) << endl;