函数名相同,参数个数不同,一看就是互为重载的两个函数,程序在编译阶段根据参数个数确定调用哪个函数。这种情况叫做静态多态(早绑定)。
动态多态是以封装和继承为基础的,且要想实现动态多态则必须使用虚函数。
多态中存在的问题:
1)内存泄漏
如果在子类中定义一个圆心的坐标,并且坐标是在堆中申请的内存,则在mian函数中通过父类指针操作子类对象的成员函数的时候是没有问题的,可是在销毁对象内存的时候则只是执行了父类的析构函数,
子类的析构函数却没有执行,这会导致内存泄漏。部分代码如下(想去借助父类指针去销毁子类对象的时候去不能去销毁子类对象)。
如果delete后边跟父类的指针则只会执行父类的析构函数,如果delete后面跟的是子类的指针,那么它即会执行子类的析构函数,也会执行父类的析构函数。
面对这种情况则需要引入虚析构函数,这样父类指针指向的是哪个对象,哪个对象的构造函数就会先执行,然后执行父类的构造函数。销毁的时候子类的析构函数也会执行。
virtual在函数中的使用限制:
1)普通函数不能是虚函数,也就是说这个函数必须是某一个类的成员函数,不可以是一个全局函数,否则会导致编译错误。
2)静态成员函数不能是虚函数 static成员函数是和类同生共处的,他不属于任何对象,使用virtual也将导致错误。
3)内联函数不能是虚函数,如果内联函数被virtual修饰,计算机会忽略inline使它变成存粹的虚函数。
4)构造函数不能是虚函数,否则会出现编译错误。
函数的覆盖和隐藏
父类和子类出现同名函数称为隐藏。
父类对象.函数名(...); //调用父类的函数
子类对象.函数名(...); //调用子类的函数??
子类对象.父类名::函数名(...); //子类调用从父类继承来的函数。
父类和子类出现同名虚函数称为覆盖
父类指针=new 子类名(...);
父类指针->函数名(...); //调用子类的虚函数。
如果父类当中定义了虚析构函数,那么父类的虚函数表当中就会有一个父类的虚析构函数的入口指针,指向的是父类的虚析构函数,子类虚函数表当中也会产生一个子类的虚析构函数的入口指针,指向的
是子类的虚析构函数,这个时候使用父类的指针指向子类的对象,delete接父类指针,就会通过指向的子类的对象找到子类的虚函数表指针,从而找到虚函数表,再虚函数表中找到子类的虚析构函数,从而
使得子类的析构函数得以执行,子类的析构函数执行之后系统会自动执行父类的虚析构函数。这个是虚析构函数的实现原理。
纯虚函数没有函数体,同时在定义的时候函数名后面要加“=0”。在虚函数原理的基础上,虚函数表中,虚函数的地址是一个有意义的值,如果是纯虚函数就实实在在的写一个0。
1)含有纯虚函数的类被称为抽象类。哪怕只有一个纯虚函数,那么这个类也是一个抽象类,纯虚函数没有函数体,所以抽象类不允许实例
化对象,抽象类的子类也可以是一个抽象类。抽象类子类只有把抽象类当中的所有的纯虚函数都做了实现才可以实例化对象。
2)如果在抽象类当中仅含有纯虚函数而不含其他任何东西,我们称之为接口类(没有任何数据成员、仅有成员函数、成员函数都是纯虚函数)。
实际的工作中接口类更多的表达一种能力或协议。

浙公网安备 33010602011771号