虚函数
定义
语法:virtual 函数返回类型 函数名(参数表) {
函数体 }
虚函数必须是基类的非
静态成员函数,其访问权限可以是private或protected或public,在基类的类定义中定义虚函数的一般形式:
class
基类名{
.......
};
作用
虚函数的作用是实现
动态联编,也就是在程序的运行阶段动态地选择合适的
成员函数,在定义了虚函数后,可以在
基类的
派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的
形参个数和形参类型。以实现统一的接口,不同定义过程。如果在
派生类中没有对虚函数重新定义,则它继承其
基类的虚函数。
例如:子类继承了父类的一个函数(方法),而我们把父类的
指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。
([2010.10.28] 注:下行语义容易使人产生理解上的偏差,实际效果应为:
如存在:Base -> Derive1 -> Derive2 及它们所拥有的虚函数func()
使用虚函数,我们可以灵活的进行
动态绑定,当然是以一定的开销为代价。如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为
纯虚函数。
函数覆盖
函数覆盖发生在父类与子类之间,其函数名、参数类型、返回值类型必须同父类中的相对应被覆盖的函数严格一致,覆盖函数和被覆盖函数只有
函数体不同,当派生类对象调用子类中该同名函数时会自动调用子类中的覆盖版本,而不是父类中的被覆盖函数版本,这种机制就叫做函数覆盖。
1。覆盖函数,即在子类中用相同的函数名和签名重写父类的方法,虚函数,在子类中用相同的函数名和签名重写父类的方法(前面有virtual关键字)。如下
2。在将父类对象的
指针指向子类对象的时候 Father* father = new Child;
如father->FunctionA(),则执行的是Father中的实现;father->FunctionB(),
则执行的是Child中的实现。
3。如果直接声明子类对象,Child child;则无论child.FunctionA()还是 child.FunctionB(),执行的都是Child中的实现。
总结:调用函数的时候,关键看对象的类型 。
记住是对象的类型,不管是
指针还是引用(同样是对象的类型)。
好了有了对象的类型就好办了。当你用这个对象(或者是
指针、引用)去调用函数时,
1:该对象(实体)即不是
指针或引用的形式,可以轻松的调用函数。
2:但是当我们用引用或
指针形式时,有个问题是区别指针(引用)的类型和指针(引用)所指实体对象的类型。
A:你用
指针来调用某函数,若函数是非
虚函数,非虚函数是
静态编译的(即编译时刻确定的)。也就是说他不会去
虚函数表找这个函数(因为不是虚函数),因 此调用的是
指针类型的那个类的相关函数。即使派生类有这个函数(这是实际编程时的大忌!!!)。这就是 你的void FunctionA() const ;