【C++】析构函数

文章目录

目录

什么是析构函数?

使用

什么时候进行调用析构函数?

构造与析构的顺序?

程序员为什么要写析构函数,什么时候写?


什么是析构函数?

  • 在开辟空间时,需要构造函数来开辟空间,对应,作用域退出时也需要一个函数做“收尾”的工作,与构造函数对应——析构函数

  • 析构函数和构造函数作用相反,用于释放对象的内存空间

  • 如果程序员未写构造函数,那么系统也会提供一个默认的构造函数,同样,如果程序员未写析构函数,那么系统也会提供一个默认的析构函数,在当前对象退出时,自动调用,进行释放空间。

使用

  • 写法:
    • ~类名
  • 析构函数无参,构造函数可以有多个参数。构造函数在构造时,值不一样就可以有多个参数进行传值,而析构函数无论带不带参数,都是将其空间释放,不需要带参数。
  • 一个类有且只有一个析构函数
    • 问:既然每个类都能提供一个默认的析构函数,而且析构函数只有一个,那为什么程序员需要写?
    • 在下面进行解答(可根据目录快速定位)

什么时候进行调用析构函数?

  • 先说结论:作用域即将消失时,进行调用构造函数
  • 下面举例解释:
  • class A{
    public:
        A(int i=4,int j=8):m_i(i),m_j(j)
        {
            cout<<"A"<
  • 代码说明:

    • 定义A类,类内定义A的构造函数,声明了两个变量:m_i,m_j

    • 构造函数A内输出“A”

    • 析构函数~A内输出“~A”,输出结果用于验证主函数内调用情况

    • 在主函数内,定义A类的对象a,对象内内有数据成员:m_i,m_j

  • 运行结果:
    • 【C++】析构函数_第1张图片
  • 结果说明:
    • 在该例题中,析构函数的调用顺序是:在a的作用域即将消失时,进行调用构造函数

构造与析构的顺序?

  • 先说结论::在同一个作用域中,构造和析构的顺序相反,先构造的后析构
  • 下面举例解释,修改上述代码:
    • 
      void main()
      {
          A a(3,6);
          A b(2,7);
          cout<<"main"<
  • 运行结果:
  • 结果分析:
    • 先构造a对象,在构造b

程序员为什么要写析构函数,什么时候写?

  • 既然每个类都能提供一个默认的析构函数,而且析构函数只有一个,那为什么程序员还要写:
  • 先说结论:当有指针作为数据成员时,就需要我们程序员自己写析构函数,将构造函数中new的空间释放掉。

下面用代码举例进行解释:

  • class Student
    {
    public:
        Student(int num=1001,char *name="baobao",char sex='f',int age=20);//含参的构造函数
        void Print();
    prvate:
         int m_num;//编号
         char *m_name;//姓名
         char m_sex;//性别
         int m_age;//年龄
    
    }
    //冒号语法进行初始化
    Student::Student(int num,char* name,char sex,int age):m_num(num),m_name(name),m_sex(sex),m_age(age)
    //在public处声明时写了默认值,定义时就不用再写啦
    {
    }
    void Student::Print()
    {
        cout<
  • 代码说明:
    • 定义student学生类,类内声明了含参的构造函数
    • 类外对构造函数进行声明
    • 对对象属性进行输出
    • 主函数内定义类的s对象并赋值然后调用输出函数
  • 输出结果:
  • 此时,输出了“pangpang”的名字。如果要对“pangpang”字符串进行修改的话,需要用指针去开辟空间存储内容该内容进行修改。将m_name指针指向name所指向的那个字符串常量的首地址,但是字符串并没有开辟空间,就不能修改,因此,只有通过给m_name指针开辟内存大小,然后再把值拷贝到该空间内就可以修改了,让指针存储值而不是指向。
  • m_name=new char[strlen(name)+1];//在堆上开辟空间
    strcpy(m_name,name);
  • 该空间的开辟是由程序员在堆上进行开辟的,需要程序员自己释放(栈上的空间不需要),因此需要写个析构函数,将构造函数中new的空间释放掉。而类内默认的析构函数没办法释放堆上的空间,只能释放栈上的,因此必须程序员自己写一个。
  • ~Student()
    {
            if(m_name!=NULL)
            {
                    delete []m_name;
                    m_name=NULL;
            }
    }

你可能感兴趣的:(C++,c++)