虚函数举例 ex14 virtual_fun01.cpp int main() Person p1("Gao Dai",18); Student stu1("Xi Jiajia",18,20150108); Person p; p=&p1; p->show();/父类指针p指向父类对象,调用的是父类的show() cout <endl; p =&stu1; p->show();/父类指针p指向派生类对象,调用的是派生类的show() return 0; http://math.ecnu.edu.cn/~jypan 7
http://math.ecnu.edu.cn/~jypan 7 虚函数举例 int main() { Person p1("Gao Dai", 18); Student stu1("Xi Jiajia", 18, 20150108); Person * p; p = &p1; p->show(); // 父类指针p指向父类对象,调用的是父类的show() cout << endl; p = &stu1; p->show(); // 父类指针p指向派生类对象,调用的是派生类的show() return 0; } ex14_virtual_fun01.cpp
几点注记 t虚函数提供了一种通过基类访问派生类功能的机制 中虚函数只能借助于指针或引用才能达到多态的效果,否则无法实现多态 ex14_virtual_fun02.cpp void fun(Person p) p->show(); /Person:show()or Student:show()? /同一段代码,可以产生不同效果→多态 推迟联编/动态联编: 一个函数的调用并不是在编译时刻被确定的,而是在程序运行时才被确定。由于 编写代码的时候并不能确定被调用的是父类的成员函数还是派生类的成员函数, 所以称为“虚”函数。 http://math.ecnu.edu.cn/~jypan 8
http://math.ecnu.edu.cn/~jypan 8 几点注记 † 虚函数提供了一种 通过基类访问派生类功能 的机制 † 虚函数只能借助于指针或引用才能达到多态的效果,否则无法实现多态 推迟联编/动态联编: 一个函数的调用并不是在编译时刻被确定的,而是在程序运行时才被确定。由于 编写代码的时候并不能确定被调用的是父类的成员函数还是派生类的成员函数, 所以称为“虚”函数。 void fun(Person * p) { p->show(); // Person:show() or Student:show()? } // 同一段代码,可以产生不同效果 多态 ex14_virtual_fun02.cpp
几点注记(续) ex14 virtual_fun03.cpp class Person { 。。。。。 virtual void show(){......} } class Student public Person { 。。 void show(){...... /可以不带virtual } 派生类中声明虚函数时,关键字virtual可以省略,这意味着,只要在父类中 声明的虚函数,则所有派生类中的同名函数(形参也相同)都是虚函数。 http://math.ecnu.edu.cn/~jypan 9
http://math.ecnu.edu.cn/~jypan 9 几点注记(续) class Person { ... ... virtual void show() { ... ... } ... ... }; class Student : public Person { ... ... void show() { ... ... } // 可以不带 virtual ... ... }; ex14_virtual_fun03.cpp † 派生类中声明虚函数时,关键字 virtual 可以省略,这意味着,只要在父类中 声明的虚函数,则所有派生类中的同名函数(形参也相同)都是虚函数
几点注记(续) ↑只需在声明处加关键字virtual,函数定义(在外部定义)时不能加 十如果派生类中没有对虚函数重新定义,则仍使用父类的虚函数 构造函数不能是虚函数,但析构函数可以 构成多态的条件 十必须存在继承关系 十继承关系中必须有虚函数,并且它们形成屏蔽关系,即父类与派生类中存在具有 相同函数原型的虚函数 ↑只能通过父类的指针或引用来调用虚函数 ex14_virtual_fun04.cpp http://math.ecnu.edu.cn/~jypan 10
http://math.ecnu.edu.cn/~jypan 10 几点注记(续) † 只需在声明处加关键字 virtual,函数定义(在外部定义)时不能加 † 如果派生类中没有对虚函数重新定义,则仍使用父类的虚函数 † 构造函数不能是虚函数,但析构函数可以 † 必须存在继承关系 † 继承关系中必须有虚函数,并且它们形成屏蔽关系,即父类与派生类中存在具有 相同函数原型的虚函数 † 只能通过父类的指针或引用来调用虚函数 构成多态的条件 ex14_virtual_fun04.cpp