zoukankan      html  css  js  c++  java
  • 010 模板函数和类

    /*
    目录:
    一: 模板函数
        1 重复函数 - 暂时
        2 函数模板 - 设计
        3 函数模板 - 原理
    二: 模板类
        1 类内编写
        2 类外编写
    */

    一: 模板函数
      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
    ", nNum1, nNum2);
        swap(nNum1, nNum2);
        printf("nNum1 = %d; nNum2 = %d
    
    ", nNum1, nNum2);
    
        // 类型 - float
        printf("fNum1 = %0.2f; fNum2 = %0.2f
    ", fNum1, fNum2);
        swap(fNum1, fNum2);
        printf("fNum1 = %0.2f; fNum2 = %0.2f
    
    ", fNum1, fNum2);
    
    
        // 类型 - double
        printf("dNum1 = %0.2f; dNum2 = %0.2f
    ", dNum1, dNum2);
        swap(dNum1, dNum2);
        printf("dNum1 = %0.2f; dNum2 = %0.2f
    ", 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
    ", nNum1, nNum2);
        swap<int>(nNum1, nNum2);
        printf("nNum1 = %d; nNum2 = %d
    
    ", nNum1, nNum2);
    
        // 类型 - float
        printf("fNum1 = %0.2f; fNum2 = %0.2f
    ", fNum1, fNum2);
        swap<float>(fNum1, fNum2);
        printf("fNum1 = %0.2f; fNum2 = %0.2f
    
    ", fNum1, fNum2);
    
    
        // 类型 - double
        printf("dNum1 = %0.2f; dNum2 = %0.2f
    ", dNum1, dNum2);
        swap<double>(dNum1, dNum2);
        printf("dNum1 = %0.2f; dNum2 = %0.2f
    ", 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 : 不同类型的函数实际拥有不同的地址,程序逻辑和大小没有改变,方便了程序员编写代码,让代码更简洁。

    二: 模板类
      1 类内编写

    // Complex.h
    #pragma once
    #include <iostream>
    
    template<class DATA>
    
    class CCmoplex
    {
    public:
        CCmoplex() : m_fReal(0), m_fImag(0)
        {
        }
    
        CCmoplex(DATA fReal, DATA fImag) : m_fReal(fReal), m_fImag(fImag)
        {
        }
    
        void Print()
        {
            cout << m_fReal << "	" << m_fImag << endl;
        }
    
    private:
        DATA m_fReal, m_fImag;
    };
    #include "stdafx.h"
    #include "Complex.h"
    
    using namespace std;
    int main(int argc, char *argv[], char **envp)
    {
        CCmoplex<int> nNum(2, 3);
        nNum.Print();
    
        CCmoplex<double> dNum(2.2, 3.3);
        dNum.Print();
    
        return 0;
    }

      2 类外编写

    #pragma once
    #include <iostream>
    
    
    template<typename DATA>
    class CCmoplex
    {
    public:
        CCmoplex();
        CCmoplex(DATA fReal, DATA fImag);
    
        void Print();
    
    private:
        DATA m_fReal, m_fImag;
    };
    
    template<typename DATA>
    CCmoplex<DATA>::CCmoplex():m_fReal(0), m_fImag(0)
    {
    }
    
    template<typename DATA>
    CCmoplex<DATA>::CCmoplex(DATA fReal, DATA fImag) : m_fReal(fReal), m_fImag(fImag)
    {
    }
    
    template<typename DATA>
    void CCmoplex<DATA>::Print()
    {
        cout << m_fReal << "	" << m_fImag << endl;
    }
  • 相关阅读:
    批量渲染烘焙贴图工具
    Reset textruemap _path of ZIP and copy allfiles to samepackage
    剔除数组中的相同元素
    选择样条曲线的OPEN 点
    帮朋友修改的小工具
    MAX脚本规范
    jQuery牛人
    最近在连远程的时候,粘贴数据库中数据信息时,为什么会不成功呢
    最近在连远程的时候,粘贴数据库中数据信息时,为什么会不成功呢
    Model层代码自动生成
  • 原文地址:https://www.cnblogs.com/huafan/p/11630174.html
Copyright © 2011-2022 走看看