首页 > 编程语言 >C++逆向分析——构造函数和析构函数

C++逆向分析——构造函数和析构函数

时间:2023-04-09 10:58:17浏览次数:33  
标签:析构 函数 int void C++ Student 和析构 构造函数

构造函数与析构函数

构造函数

struct Student { int a; int b;   Student() { printf("Look."); }   void Init(int a, int b) { this->a = a; this->b = b; }   };

如上代码中,我们发现了存在一个函数,这个函数没有返回类型并且与结构体名称一样,那这段函数在什么时候执行呢?

我们先不使用之前学习的方法去调用,直接创建一个对象,这时候会发现该函数就直接执行了:

images/download/attachments/12714553/image2021-3-31_17-4-32.png

这个函数,我们就称之为构造函数。

它的汇编代码如下:

images/download/attachments/12714553/image2021-3-31_17-30-51.png

如果我们想要在创建对象的时候,自定义初始化成员的值,就可以在析构函数上加上参数:

struct Student { int a; int b;   Student(int a, int b) { this->a = a; this->b = b; }   void Init(int a, int b) { this->a = a; this->b = b; }   };   void main() { Student s(1, 2);   return; }

创建对象的时候,在对象名后面加上括号传入即可;但是这样就会存在一个问题,我们不想初始化值的时候就没有办法创建这个类:

struct Student { int a; int b;   Student(int a, int b) { this->a = a; this->b = b; }   void Init(int a, int b) { this->a = a; this->b = b; }   };   void main() { Student s;   return; }

编译直接出错:

images/download/attachments/12714553/image2021-4-1_15-42-56.png

这是因为编译器发现你没有传入参数,就会去寻找没有参数的构造函数,但是在这段代码中没有声明,所以需要声明一下:

#include <stdio.h> struct Student { int a; int b;   Student() { printf("Look."); }   Student(int a, int b) { this->a = a; this->b = b; }   void Init(int a, int b) { this->a = a; this->b = b; }   };   void main() { Student s;   return; }

这样就没有任何问题了,你想传参就传,不想就不传。

我们总结一下其(构造函数)特点

  1. 构造函数名称与类名一样

  2. 不能写返回类型(无返回值)

  3. 创建对象时,则会自动调用执行,一般用于初始化

  4. 可以有多个构造函数(建议只有一个无参的),这种声明方式我们称之为重载(其他函数也可以)

  5. 编译器不要求必须提供构造函数

析构函数

析构函数函数的语法跟构造函数很像,其区别就是:析构函数需要在函数名前面加一个波浪号析构函数只能有一个析构函数函数不可以写参数构造函数是创建对象的时候执行,但是析构函数函数是在对象销毁前执行

#include <stdio.h> struct Student { int a; int b;   Student() { printf("Look."); }   Student(int a, int b) { this->a = a; this->b = b; }   ~Student() { printf("Look A."); }   void Init(int a, int b) { this->a = a; this->b = b; }   };   void main() { Student s;   return; }

析构函数函数是在对象销毁前执行,那么对象会在什么时候销毁呢?可以看下反汇编代码:

images/download/attachments/12714553/image2021-4-1_16-9-20.png

会发现在程序执行结束,也就是main函数的return之后会执行析构函数函数,但这句话实际上是不严谨的,因为我们的main函数是没有返回值的,也就是return不会有对应的汇编代码,当我们设置返回值再来看下反汇编代码:

#include <stdio.h> struct Student { int a; int b;   Student() { printf("Look."); }   Student(int a, int b) { this->a = a; this->b = b; }   ~Student() { printf("Look A."); }   void Init(int a, int b) { this->a = a; this->b = b; }   };   int main() { Student s;   return 0; }

images/download/attachments/12714553/image2021-4-1_16-12-49.png

可以很清晰的看见,析构函数是在return返回之前执行的。

我们总结(析构函数)一下:

  1. 只能有一个,不支持重载

  2. 无返回值

  3. 无任何参数

  4. 主要用于清理工作

  5. 编译器不要求必须提供

  6. 当对象在main函数(堆栈)中创建,在return之前调用执行;当对象在全局变量区,则会在应用程序退出之前调用

标签:析构,函数,int,void,C++,Student,和析构,构造函数
From: https://www.cnblogs.com/bonelee/p/17299976.html

相关文章

  • 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是等价的,但是可以屏蔽一些底层细节,因为不一定所有平台都提供统一的内存分配方式,所以需要......
  • 2023年第14届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组
    2023年第14届蓝桥杯大赛软件赛省赛C/C++大学B组试题A:日期统计(5)直接暴力,8个for+优化,2~5分钟跑完。答案:365点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=1e6+10,INF=0x3f3f3f3f;intmon[]={0,31,28,......