首页 > 编程语言 >C++逆向分析——模版

C++逆向分析——模版

时间:2023-04-09 11:01:07浏览次数:38  
标签:逆向 arr return 函数 int 模版 C++ nLength 模板

模版

假设有一个冒泡排序的函数:

void Sort(int* arr, int nLength) { int i, k; for (i = 0; i < nLength; i++) { for (k = 0; k < nLength-1-i; k++) { if(arr[k] > arr[k+1]) { int temp = arr[k]; arr[k] = arr[k+1]; arr[k+1] = temp; } } } }

但是这个冒泡排序的函数只能对int类型,如果我们想要使用char类型的时候就要重新写一个函数,这就违背了C++的初衷,重复造轮子了:

images/download/attachments/12714553/image2021-4-17_11-17-32.png

那么如何避免重复造轮子呢?C++中使用模板来解决这个问题。

函数模板的语法是这样的:

template<class 形参名, class 形参名, ...> 返回类型 函数名(参数列表) { 函数体; }

用模板的方式来修改一下这个冒泡排序函数:

template<class T> void Sort(T* arr, int nLength) { int i, k; for (i = 0; i < nLength; i++) { for (k = 0; k < nLength-1-i; k++) { if(arr[k] > arr[k+1]) { T temp = arr[k]; arr[k] = arr[k+1]; arr[k+1] = temp; } } } }

在当前这个函数中我们只有一个地方需要替换修改,所以在写模板关键词时候尖括号内的class形参只有一个,而我们只需要将需要替换的地方改成形参的名字即可。

那么模版其原理是什么,编译器做了什么工作呢?我们可以看一下如下代码的反汇编代码:

images/download/attachments/12714553/image2021-4-17_11-34-34.png

使用不同类型的数组传入冒泡排序函数,观察一下执行地址:

images/download/attachments/12714553/image2021-4-17_11-33-30.png

可以看见,两个函数的地址完全不一样,这就说明模板的本质就是编译器会在看见不同的传入类型时创建不同的函数

模板除了可以在函数中使用也可以在结构体(类)中使用模板,其格式如下所示:

template<class 形参名, class 形参名, ...> class 类名 { ...; }

如下代码,一个结构体,有两个成员函数,一个是比较返回最大的数,一个则是最小的数:

struct Base { int a; int b;   char x; char y;   int Max() { if (a>b) { return a; } else { return b; } }   char Min() { if (x<y) { return x; } else { return y; } } };

但这个结构体已经指定了成员变量的数据宽度int、char,而我们想要比较任意类型的话,可以使用模板改造下这段代码:

template<class T, class M> struct Base { T a; T b;   M x; M y;   T Max() { if (a>b) { return a; } else { return b; } }   M Min() { if (x<y) { return x; } else { return y; } } };

这个模板想使用的话,我们就需要告诉编译器模板中的T、M分别对应什么,所以如果直接使用Base b;则无法编译。

使用如下格式即可:

Base<int, char> b;

images/download/attachments/12714553/image2021-4-17_15-11-54.png

标签:逆向,arr,return,函数,int,模版,C++,nLength,模板
From: https://www.cnblogs.com/bonelee/p/17299998.html

相关文章

  • C++逆向分析——构造函数和析构函数
    构造函数与析构函数构造函数structStudent{inta;intb; Student(){printf("Look.");} voidInit(inta,intb){this->a=a;this->b=b;} };如上代码中,我们发现了存在一个函数,这个函数没有返回类型并且与结构体名称一样,那这段函数在什么......
  • Code-C++ Invoke Python
    Code-C++InvokePythonhttps://www.cnblogs.com/yongchao/p/17299892.html使用C或C++扩展Python扩展和嵌入Python解释器Python3.10.11Python/CAPI参考手册Python3.11.3Python/CAPI参考手册https://www.cnblogs.com/lidabo/p/17043302.htmlhttps://bl......
  • C++逆向分析——继承
    继承structPerson{intage;intsex;}; structTeacher{intage;intsex;intlevel;intclassId;};如上代码中可以看见,Teacher类与Person类都存在着相同的2个成员age和sex,那么这就相当于重复编写了,我们可以通过继承的方式避免这样重复的编写(当前类名称:......
  • C++逆向分析——new和delete new[]和delete[]
    在堆中创建对象我们可以在什么地方创建对象?全局变量区,在函数外面在栈中创建对象,也就是函数内在堆中创建对象注意:之前一直提到的堆栈实际上是两个概念->堆、栈,我们之前所讲的就是栈,从本章开始要严格区分。在C语言中,我们可以通过一个函数去申请一块内存,就是malloc(N)......
  • C++逆向分析——类成员的访问控制
    类成员的访问控制课外→好的编程习惯:定义与实现分开写,提升代码可读性。如下代码,Student这个类的所有成员我们都可以调用,但是我们不想让被人调用Print1这个方法该怎么?structStudent{intage;intsex; voidPrint1(){printf("FuncPrint1");} voidPrint......
  • C++逆向分析——引用
    引用类型引用类型就是变量的别名,其在初始化时必须要赋值。//基本类型intx=1;int&ref=x;ref=2;printf("%d\n",ref); //类Personp;Person&ref=p;ref.x=10;printf("%d\n",p.x); //指针类型int******x=(int******)1;int******&ref=x;r......
  • C++逆向分析——继承与封装
    面向对象程序设计之继承与封装之前已经学习过继承和封装了,但是要在实际开发中使用,光学语法和原理是不够的,在设计层面我们需要做一些优化。如下代码是继承的例子:#include<stdio.h> classPerson{public:intAge;intSex; voidWork(){printf("Person:Work()......
  • C++逆向分析——多态和虚表
    虚表上一章了解了多态,那么我们来了解一下多态在C++中是如何实现的。了解本质,那就通过反汇编代码去看就行了,首先我们看下非多态的情况下的反汇编代码:然后再来看下多态情况下的反汇编代码:很明显这里多态的情况下会根据edx间接调用,而非多态则会直接调用。那么我们来看下间接......
  • OS-Linux-Ubuntu22.04x64-Python-C++调用Python缺少Python.h
    OS-Linux-Ubuntu22.04x64-Python-C++调用Python缺少Python.h使用C或C++扩展Python扩展和嵌入Python解释器Python3.10.11Python/CAPI参考手册Python3.11.3Python/CAPI参考手册参考https://www.cnblogs.com/lidabo/p/17043302.htmlhttps://blog.csdn.net/z......
  • C++ Allocator
    C++Allocator该开始搞项目了,但是在搞项目之前,先搞一下C++的Allocator,因为项目中会用到。现在还不确定到底模仿哪个,jemalloc和tcmalloc,先看看吧。1.为什么需要Allocator其实和new/delete是等价的,但是可以屏蔽一些底层细节,因为不一定所有平台都提供统一的内存分配方式,所以需要......