面试常见题之析构函数为虚函数

来源:互联网 发布:淘宝网上有毛片买吗 编辑:程序博客网 时间:2024/05/17 22:38

   可以说百分之八十的IT公司在面试的时候都会问你有关虚函数的问题,尤其是析构函数为什么要用虚函数,一句话说白了,就是内存泄露的问题,在公有继承中,基类对派生类对象的操作,只能影响到那些从基类继承下来的成员,如果想要用基类对非继承的成员进行操作,则需将基类的这个函数定义为虚函数。

  如下面的例子

class A{public:A(){};~A(){cout<<"A is destructed"<<endl;};};class B :public A{public:B(){};~B(){cout<<"B is destructed"<<endl;};};void main(){A* b = new B;delete b;}


则最后输出的结果为 A is destructed,

在这个例子的main函数中,我们用了A类的指针去操作B类的对象,而在我们释放掉A类的指针之后,我们调用的析构函数是A类的析构函数,释放的是基类的资源,一般情况下,这样的删除只能删除基类对象,而不能删除子类对象,这样就造成了内存泄露。

因此,我们对上面的例子进行修改如下

class A{public:A(){};virtual ~A(){cout<<"A is destructed"<<endl;};};class B :public A{public:B(){};~B(){cout<<"B is destructed"<<endl;};};void main(){A* b = new B;delete b;}


则最后的输出结果为

B is destructed

A is destructed

上面的代码中,析构函数被定义为虚函数,用A类的指针去操作B类的对象,释放指针b的过程为,先释放掉继承类的资源,在释放掉基类的资源。

如果不需要基类对派生类或派生类的对象进行操作,则不能将析构函数定义为虚函数,因为这样会增加内存的开销,我们知道,当你定义一个类的时候,编译器会为这个类增加一个虚函数表,里面存放虚函数指针,这样就会增加类的存储空间,只有当一个类为基类的时候,析构函数才定义为虚函数。

我们再来看下面的例子

class A{public:A(){};void print(){cout<<"A is printing......"<<endl;};virtual ~A(){cout<<"A is destructed"<<endl;};};class B :public A{public:B(){};void print(){cout<<"B is printing......"<<endl;};~B(){cout<<"B is destructed"<<endl;};};void main(){A* b = new B;b->print();delete b;}

则输出的结果为

A  is printing......

B is destructed

A is destructed

当我们将类中的函数 print()定义为虚函数的时候,代码如下

class A{public:A(){};virtual void print(){cout<<"A is printing......"<<endl;};virtual ~A(){cout<<"A is destructed"<<endl;};};class B :public A{public:B(){};virtual void print(){cout<<"B is printing......"<<endl;};~B(){cout<<"B is destructed"<<endl;};};void main(){A* b = new B;b->print();delete b;}


则最后输出的结果为

B  is printing......

B  is destructed

A  is destructed

从而说明如果想要用基类对非继承的成员进行操作,则需将基类的这个函数定义为虚函数。


 

 

0 0
原创粉丝点击