构造函数能不能声明为虚函数,析构函数呢?为什么?

一:构造函数不能声明为虚函数的原因?

构造一个对象时,必须知道对象实际类型,而虚函数是在运行期间确定实际类型的。而在构造一个对象时,由于对象还未构造成功,编译器就无法知道对象的实际类型,是该类本身,还是派生类,还是其他。

虚函数的执行依赖于虚函数表,而虚函数表是在构造函数中进行初始化的,即初始化虚表指针(vptr),使得正确指向虚函数表。而在构造对象期间,虚函数表(vtable)还没有被初始化,将无法进行。

二:析构函数设为虚函数的原因?

析构函数的作用在对象撤销前把类的对象从内存中撤掉,通常系统只会执行基类的析构函数,不执行派生类的析构函数。

将基类的析构函数声明为虚函数,当撤销基类对象的同时也撤销派生类的对象,这个过程是动态关联完成的。

析构函数设为虚函数的原因是为了防止内存泄露。在继承体系中,当基类的指针或引用指向派生类,用基类delete时,如果析构函数没有声明为虚函数,只能析构基类对象,派生类对象将无法析构。

建议将析构函数设为虚函数。

  • 说明:

使用虚函数,系统会有一定的空间开销。当一个类带有虚函数时,编译系统会为该类构造一个虚函数表,是一个指针数组,存放每个虚函数的入口地址。系统在进行动态关联的时间开销很少,提高了多态性的效率。

编译器生成的析构函数都是非虚的,除非是一个子类,其父类有个虚析构函数,此时的虚函数特性继承自基类。

有虚函数的类,一般情况下要定义一个虚析构函数。

猜你喜欢

转载自blog.csdn.net/m0_37925202/article/details/81413693