虚函数是动态绑定的基础,虚函数必须是非静态的成员函数。
根据赋值兼容机制,可以使用派生类的对象来代替基类的对象,但if用基类类型的指针指向派生类的对象时,访问到的只是从基类继承而来的同名成员,那么当我们要访问到派生类的同名成员时该怎么做呢?
可以将基类中的同名成员声明为虚函数,这样就可以通过基类类型的指针,使不同派生类的不同对象产生不同的行为,从而实现运行过程的多态。
一、一般虚函数
syntax:
virtual returnType functonName (形参表);
虚函数声明只能出现在类定义中的函数原型声明中,不能再成员函数实现中。
运行过程中多态需满足三个条件:
1)赋值兼容机制;
2)声明虚函数;
3)由成员函数调用 OR 通过指针、引用来访问虚函数。
if 使用对象名来访问虚函数,则绑定在编译过程就进行(静态绑定)。
编程习惯:虚函数不以内联函数处理。
if 派生类没有给出显示虚函数声明,系统怎么判断派生类的函数成员是否虚函数?
1)是否与基类虚函数有相同名称;
2)是否与基类虚函数有相同参数个数与相同的对应参数类型;
3)是否与基类虚函数有相同的返回值OR满足赋值兼容规则的指针、引用型的返回值。
三者满足其一,就会自动确定为虚函数,这样派生类的虚函数便覆盖了基类的虚函数,同时亦会隐藏基类同名函数的所有其他重载形式。
if此时用指向派生类对象的指针调用基类中被派生类覆盖的成员函数,要使用作用域分辨符::
习惯:在派生类的函数中也使用virtual关键字。
要注意的是基类的构造函数以及析构函数是不会调用派生类的虚函数的。
再从写继承而来的虚函数时,if 函数有默认形参值,不要重新定义不同的值,虽然虚函数是动态绑定的,但默认形参值是静态绑定的,通过一个指向派生类对象的基类指针,可以访问到派生类的虚函数,但默认形参表只能来自基类的定义。
注意 只有通过基类的指针或引用调用虚函数时,才会发生动态绑定!!!!!
如果不是这样,就只是利用派生类对象复制构造基类对象,这种行为称作对象切片。
二、虚析构函数
在C++中,不能声明虚构造函数,但可以声明虚析构函数
syntax:
virtual ~类名();
if一个类的析构函数是虚函数,那么由他派生而来的所有子类的析构函数也是虚函数,if有可能通过基类指针调用对象的析构函数,就需要让基类的析构函数成为虚函数。