c++里面虚函数与析构函数的关联

c++里面虚函数与析构函数的关联

首先介绍一下什么是虚函数和析构函数?
虚函数定义:
在基类中用关键字virtual修饰,在派生类中进行重新定义的函数。

virtual 函数类型 函数名(形参表){
	      函数体;
}

虚函数的作用:
用于实现C++的多态,通过基类的指针可以访问派生类中同名的函数。
实例:

#include<iostream>
using namespace std;
class A {
    public:
    virtual void fun() {
    	cout << "this is A!" <<endl;
    }
};

class B:public A {	
    public:
    void fun() {
        cout << "this is B!" <<endl;
    }
};

int main() {	
    A *p1, *p2;
    A a;
    B b;
    p1 = &a;   //基类的指针指向基类的对象
    p2 = &b;   //基类的指针指向派生类的对象
    p1->fun();
    p2->fun();
    return 0;
}
/*输出结果*/
this is A!    
this is B!

析构函数的定义:
成员函数的一种,一个类只能有一个析构函数,如果没有单独定义,会默认生成。

~ 类名(){
}

析构函数的作用:
析构函数在对象消亡时会自动被调用,常常被用来用做一些对象消亡时的善后工作,比如说释放用new申请的空间。
实例:

#include <iostream>
using namespace std;
class A {
    public:
    ~ A() {
        cout <<"析构函数"<<endl;
    }
};

int main() {
    A *p = new A;
    delete p;	//delete一个对象,会调用析构函数
    return 0;
}
/*输出结果*/
析构函数

析构函数与虚函数的关系?
一.为什么析构函数必须是虚函数
防止内存泄漏,假如析构函数不是用的虚函数有可能会发生内存泄漏,实例:

#include<iostream>
using namespace std;
class A {
    private:
    	int *num_a;
    public:
    	virtual void fun() {
    		cout << "this is A!" <<endl;
    	}
    	A() {
        	num_a = new int[10];
        	cout<< "A 构造" <<endl;
    	}
    	~ A() {
        	delete[] num_a;
        	cout << "A 析构" << endl;
    	}
};

class B:public A {	
    private:
        int * num_b;
    public:
    	void fun() {
        	cout << "this is B!" <<endl;
    	}
    	B() {
        	num_b = new int[10];
        	cout <<"B 构造"<<endl;
    	}
    	~B() {
        	delete num_b;
        	cout << "B 析构" <<endl;
    	}
};

int main() {	
    A *p1 = new B;
    delete p1;
    return 0;
}
/*
   B b;
   A *p1 = &b;
   delete p1 报错
   p1 不是通过new 得到新的内存空间,而是直接指向固定变量b。所以删除p1等同要强行剥夺b的固有空间,会导致出错   
*/
/*输出结果*/
A 构造
B 构造
A 析构
因为析构函数不是虚函数,所以基类的指针不会调用到派生类的析构函数
这样就导致了B构造函数中的内存没有得到释放,**造成了内存泄漏**。

此时将A的析构函数改为虚函数
class A {
    private:
    	int *num_a;
    public:
    	virtual void fun() {
    		cout << "this is A!" <<endl;
    	}
    	A() {
        	num_a = new int[10];
        	cout<< "A 构造" <<endl;
    	}
    	virtual ~ A() {
        	delete[] num_a;
        	cout << "A 析构" << endl;
    	}
};
/*运行结果*/
A 构造
B 构造
B 析构
A 析构
这样就避免了内存泄漏

二.那默认的析构函数是不是虚函数
答案:不是
原因:因为虚函数是需要额外的虚函数表和虚表指针,会占用内存,如果用不到基类的指针调用派生类的方法,会浪费内存,所以默认的析构函数不是虚函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值