小编话不多说,接着上篇的写。
虚函数
当父类指针或引用指向子类对象,而子类中又覆盖了父类的函数,希望用父类指针或父类引用,调用到正确的版本的函数(即子类中的函数),需要把该函数成员声明为虚函数。
虚析构函数
如果一个类有子类,则这个类(父类)的析构函数必须是虚函数,即虚析构。
写法:virtual~A
为什么要定义虚析构函数:(原因)
如果父类的析构不虚析构,则当(用delete)删除一个指向子类对象的父类指针时,将调用父类版本的析构函数,子类只会释放了来自于父类的那部分成员变量,而子类自己扩展的成员没有被释放,造成内存泄露。
这里会涉及动态绑定,里边设计内容稍多点,小编我转载了一篇很好的博客,有兴趣的可以看一下,标题是c++静态绑定和动态绑定。
多态的代价:
因为我们使用了虚函数实现多态,在使用虚函数时,会给对象附带一个虚指针,然后给类中添加虚函数表,这个虚指针指向虚函数表,虚函数表当中,包含有所有指向虚函数的指针,此时,我们通过类的对象去调用虚函数,首先会通过虚指针去寻找虚函数表,通过虚函数表中的函数指针去寻找虚函数,这样就会进行2次寻址,降低了程序运行的效率,并且对象中的虚指针增加了内存空间,这就是使用多态的代价。
抽象基类和纯虚函数:
纯虚函数:虚函数末尾=0,这个函数就是纯虚函数,他没有函数体,不需要实现。例如:virtual void draw()=0;
纯虚函数的作用:提供了子类公用的统一接口。
抽象类:拥有纯虚函数的类叫做抽象类,抽象类无非实现实例化。
抽象基类:只能作为基类的抽象类。
子类继承了抽象类后,如果在子类中没有实现父类的全部的纯虚函数,那么这个子类也将成为抽象类,无法创建对象。
多继承
多继承指一个子类有两个或者两个以上的父类。
多继承通常是导致程序出现问题的原因。
多继承主要有三个常见问题:
(1) 不同父类有同名函数,如何区分?
(2) 两个父类有共同的祖先。
解决办法:
(1)直接继承祖先的两个父类,在继承时加virtual。(两个父类虚继承父类,子类调用这个同名函数时会直接调用祖先类)。
(2)通过多重继承而来的那个子类(孙子辈),在构造函数时,要调用祖先类的构造函数。孙子辈的派生类,直接继承祖先类的成员,再继承两个父类各自拓展的成员。