C++ Primer Plus学习笔记之虚函数
C++语言的多态性有两种类型:静态多态性和动态多态性。函数重载和运算符重载就是静态多态性的具体表现,而动态多态性是指程序运行过程中才动态的确定操作所针对的对象,它是通过虚函数实现的;
1,虚函数的概念:
一个指向基类的指针可用来指向从基类派生的任何对象,这样就可以达到一个接口多个实现的访问了;虚函数是在基类中被冠以virtual的成员函数,它提供了一种接口界面。虚函数可以在一个或者多个派生类中被重新定义,但要求在派生类中从新定义时,虚函数的函数原型,包括返回值,函数名,参数名,参数个数,参数类型的顺序必须完全相同;
2,晚期匹配是怎么发生的???
所有的工作由编译器在幕后完成。为了完成这件事,编译器对每个包含虚函数的类创建一个表成为VTABLE。在VTABLE中,编译器放置特定类的虚函数地址。在每个带有虚函数的类中,编译器秘密的置一指针,成为VPTR指向这个对象的VTABLE。通过基类指针做虚函数调用时,编译器静态的插入取得这个VPTR,并在VTABLE表中查找函数地址的代码。
3,虚特性:
用虚函数实现运行时多态性德关键之处是:必须使用指向基类的指针或引用访问虚函数。
注意:
在派生类中重新定义基类的虚函数是函数重载的另一种特殊形式,它不属于一般的函数重载。当重载一般函数时,仅要求函数名相同,但重载一个虚函数时,要求函数名,返回类型,参数个数,参数类型,参数顺序完全相同,否则会导致虚特性丢失;
#include<iostream> using namespace std; class figure { public: void set(double i=0,double j=0) { x=i; y=j; } virtual void show_area() { cout<<"No area computation defined for this class"<<endl; } protected: double x; double y; }; class triangle:public figure { public: void show_area() { cout<<"Triangle with high "<<x<<" and base "<<y; cout<<" has an area of "<<0.5*x*y<<endl; } }; class square:public figure { public: void show_area() { cout<<"Square with dimension "<<x<<"*"<<y; cout<<" has an area of "<<x*y<<endl; } }; class circle:public figure { public: void show_area() { cout<<"Circle with radius "<<x; cout<<" has an area of "<<3.14*x*x<<endl; } }; int main(int argc,char *argv[]) { figure *f; triangle t; square s; circle c; f=&t; f->set(10,5); f->show_area(); f=&s; f->set(10,5); f->show_area(); f=&c; f->set(10); f->show_area(); return 0; }运行结果:
Triangle with high 10 and base 5 has an area of 25
Square with dimension 10*5 has an area of 50
Circle with radius 10 has an area of 314