/* 目录: 一: 模板函数 1 重复函数 2 函数模板 - 设计 3 函数模板 - 原理 */
一: 模板函数
1 重复函数
#include "stdafx.h" using namespace std; void swap(int &a, int &b) { int t = a; a = b; b = t; } void swap(float &a, float &b) { float t = a; a = b; b = t; } void swap(double &a, double &b) { double t = a; a = b; b = t; } int main(int argc, char *argv[], char **envp) { int nNum1 = 3, nNum2 = 4; float fNum1 = 3.1, fNum2 = 4.2; double dNum1 = 3.11, dNum2 = 4.22; // 类型 - int printf("nNum1 = %d; nNum2 = %d\n", nNum1, nNum2); swap(nNum1, nNum2); printf("nNum1 = %d; nNum2 = %d\n\n", nNum1, nNum2); // 类型 - float printf("fNum1 = %0.2f; fNum2 = %0.2f\n", fNum1, fNum2); swap(fNum1, fNum2); printf("fNum1 = %0.2f; fNum2 = %0.2f\n\n", fNum1, fNum2); // 类型 - double printf("dNum1 = %0.2f; dNum2 = %0.2f\n", dNum1, dNum2); swap(dNum1, dNum2); printf("dNum1 = %0.2f; dNum2 = %0.2f\n", dNum1, dNum2); return 0; }
1 : 同步骤,不同类型的函数,需要编写三个函数,好麻烦。
2 函数模板 - 设计
#include "stdafx.h" using namespace std; template<class T> void swap(T &a, T &b) { T t = a; a = b; b = t; } int main(int argc, char *argv[], char **envp) { int nNum1 = 3, nNum2 = 4; float fNum1 = 3.1, fNum2 = 4.2; double dNum1 = 3.11, dNum2 = 4.22; // 类型 - int printf("nNum1 = %d; nNum2 = %d\n", nNum1, nNum2); swap<int>(nNum1, nNum2); printf("nNum1 = %d; nNum2 = %d\n\n", nNum1, nNum2); // 类型 - float printf("fNum1 = %0.2f; fNum2 = %0.2f\n", fNum1, fNum2); swap<float>(fNum1, fNum2); printf("fNum1 = %0.2f; fNum2 = %0.2f\n\n", fNum1, fNum2); // 类型 - double printf("dNum1 = %0.2f; dNum2 = %0.2f\n", dNum1, dNum2); swap<double>(dNum1, dNum2); printf("dNum1 = %0.2f; dNum2 = %0.2f\n", dNum1, dNum2); return 0; }
1 : 把类型提取出来,流程通用,把三个函数转为一个模板,方便多了。
3 函数模板 - 原理
23: swap<int>(nNum1, nNum2); 004168D5 lea eax,[nNum2] 004168D8 push eax 004168D9 lea ecx,[nNum1] 004168DC push ecx 004168DD call swap<int> (0411005h) 004168E2 add esp,8 00411005 jmp swap<int> (0411990h) // 函数地址 - int类型 8: void swap(T &a, T &b) 9: { 00411990 push ebp 00411991 mov ebp,esp 00411993 sub esp,0CCh 00411999 push ebx 0041199A push esi 0041199B push edi 0041199C lea edi,[ebp-0CCh] 004119A2 mov ecx,33h 004119A7 mov eax,0CCCCCCCCh 004119AC rep stos dword ptr es:[edi] 10: T t = a; 004119AE mov eax,dword ptr [a] 004119B1 mov ecx,dword ptr [eax] 004119B3 mov dword ptr [t],ecx 11: a = b; 004119B6 mov eax,dword ptr [a] 004119B9 mov ecx,dword ptr [b] 004119BC mov edx,dword ptr [ecx] 004119BE mov dword ptr [eax],edx 12: b = t; 004119C0 mov eax,dword ptr [b] 004119C3 mov ecx,dword ptr [t] 004119C6 mov dword ptr [eax],ecx 13: } 004119C8 pop edi 13: } 004119C9 pop esi 004119CA pop ebx 004119CB mov esp,ebp 004119CD pop ebp 004119CE ret
28: swap<float>(fNum1, fNum2); 00416921 lea eax,[fNum2] 00416924 push eax 00416925 lea ecx,[fNum1] 00416928 push ecx 00416929 call swap<float> (04114B5h) 0041692E add esp,8 004114B5 jmp swap<float> (04119D0h) // 函数地址 - float类型 7: template<class T> 8: void swap(T &a, T &b) 9: { 004119D0 push ebp 004119D1 mov ebp,esp 004119D3 sub esp,0CCh 004119D9 push ebx 004119DA push esi 004119DB push edi 004119DC lea edi,[ebp-0CCh] 004119E2 mov ecx,33h 004119E7 mov eax,0CCCCCCCCh 004119EC rep stos dword ptr es:[edi] 10: T t = a; 004119EE mov eax,dword ptr [a] 004119F1 movss xmm0,dword ptr [eax] 004119F5 movss dword ptr [t],xmm0 11: a = b; 004119FA mov eax,dword ptr [a] 004119FD mov ecx,dword ptr [b] 00411A00 mov edx,dword ptr [ecx] 00411A02 mov dword ptr [eax],edx 12: b = t; 00411A04 mov eax,dword ptr [b] 00411A07 movss xmm0,dword ptr [t] 00411A0C movss dword ptr [eax],xmm0 13: } 00411A10 pop edi 13: } 00411A11 pop esi 00411A12 pop ebx 00411A13 mov esp,ebp 00411A15 pop ebp 00411A16 ret
1 : 函数类型int跳转地址: jmp swap<int> (0411990h);
2 : 函数类型float跳转地址: jmp swap<float> (04119D0h)
3 : 不同类型的函数实际拥有不同的地址,程序逻辑和大小没有改变,方便了程序员编写代码,让代码更简洁。
原文:https://www.cnblogs.com/huafan/p/11630174.html