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";}

}

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

1)

A* p = new B;

delete p;

p->a 等于多少?

2)

析构函数的打印顺序.

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

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

构造函数:

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

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

析构函数:

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

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

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

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

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

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

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

猜你喜欢

转载自blog.csdn.net/lin_cloud211/article/details/81218261
今日推荐