继承中,构造函数,赋值操作符,析构函数与虚函数的关系

为什么构造函数不能是虚函数呢?这里你需要知道一个概念,那就是虚函数表vtbl,每一个拥有虚成员函数的类都有一个指向虚函数表的指针。对象通过虚函数表里存储的虚函数地址来调用虚函数。那虚函数表指针是什么时候初始化的呢?当然是构造函数。当我们通过new来创建一个对象的时候,第一步是申请需要的内存,第二步就是调用构造函数。试想,如果构造函数是虚函数,那必然需要通过vtbl来找到虚构造函数的入口地址,显然,我们申请的内存还没有做任何初始化,不可能有vtbl的。因此,构造函数不能是虚函数。


赋值操作符设为虚函数可能会令人混淆,因为虚函数必须在基类和派生类中具有相同的形参。基类赋值操作符有一个形参是自身类类型的引用,如果该操作符为虚函数,则每个类都得到一个虚函数成员,该成员定义了参数为一个基类对象的operator=。但是对派生类而言,这个操作符是基类的行为,并不是派生类的行为,往往得出不同的结果。


基类中的析构函数必须为虚函数。试看基类Base和派生类ItemP的例子。  Base* base=new Itemp, 基类指针指向派生类类对象时,发生假切割。要知道这个过程只是切掉基类中没有的那些成员。当delete base时,若析构函数没有定义为虚函数,则实际删除基类部分,而派生类部分的数据成员仍然存在内存中,从而造成内存泄漏。而定义为虚函数,则会根据动态对象调用适当的析构函数。

猜你喜欢

转载自blog.csdn.net/lzkIT/article/details/20722859
今日推荐