C++构造函数和析构函数--从常见的面试题说起系列1

class A

{

public:

    A(){a=0}

    virtual ~A(){printf("aaa");}

private:

    int a;

}

class B: public A

{

public:

    B(){a=2}

    virtual ~B(){printf("bbb\n");}

}

常常有这样两个面试题目:

1)

A* p = new B;

p->a 等于多少?

2)

析构函数的打印顺序.

类A 和 类B的析构函数为什么要定义为虚函数,如果不定义为虚函数会有什么问题或隐患?

如第一题后面,增加  delete p; 则会打印什么?

其实这两道题目就是考的C++中类的构造函数和析构函数的调用顺序问题,其中第一套题比较简单,大部分面试者都能正确回答,第二道题回答完整的就比较少了,第二题还考到了多态(虚函数)的知识点,多态在后续的文章单独阐述。

构造函数:

对于有继承关系的构造函数,定义子类的对象时,会先调用父类的构造函数,再调用子类的析构函数。

因此第一套题先会调用A的构造函数,此时p->a为0,然后调用B的构造函数,最终p->a的值为2.

析构函数:

对于析构函数,大部分面试者回答的比较简单,回答的不够全面。

删除对象时,调用的第一个析构函数,由析构函数是否是虚函数确定:

1)如果是虚函数,则会调用指针指向的实际对象的类的析构函数,但是析构函数不仅仅是虚函数,它还会自动往上调用基类的析构函数。

2)如果不是虚函数,则由删除指针定义的类型来确定。

这道题中,delete p时,由于是析构函数,则会先调用B的析构函数,再调用A的析构函数

如果不是虚函数,则只会调用A的析构函数。但是如果是 B* p = new B的话,即使不是虚函数,也一样会先调用B的析构函数,再调用A的析构函数。

因此第二题打印的是:

bbb

aaa

类成员申请的资源通常都是在析构函数中释放,由于析构函数的这个特点,因此析构函数通常定义为虚函数,因为如果不是虚函数的话,很有可能不会调用到子类的析构函数,导致子类申请的资源没有被释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值