C/C++中虚函数的使用方法带示例
C++中的虚函数主要是为啦实现C++的多态性
C++在同一类中是不能定义两个名字、参数个数和类型都相同的函数的,否则就是“重复定义”。
但是在类的继承层次结构中,在不同的层次中可以出现名字相同、参数个数和类型都相同而功能不同的函数。
看下面代码
首先来看下继承关系中的指针指向问题:
如果有一个基类,并且基类有一个派生类,两者都有一个相同的方法
这时候声明一个基类的指针,基类指针本来是用来指向基类对象的,如果把用它指向派生类对象(把派生类对象的指针赋值给它),则会进行指针类型转换,将派生类对象的指针先转换为基类类型的指针,所以基类指针指向的是派生类对象中的基类部分,调用的还是基类中的方法
如下面例子
#include <iostream> #include <string> using namespace std; class A { public: A(string n,string s); void show(); protected: string name; string sex; }; A::A(string n,string s){ name=n; sex=s; } void A::show(){ cout<<"A class method: "<<name<<"-->"<<sex<<endl; } //B类继承A类 class B:public A { public: B(string n,string s,int a); void show(); protected: int age; }; B::B(string n,string s,int a):A(n,s){ age=a; } void B::show(){ cout<<"B class method: "<<name<<"-->"<<sex<<"--"<<age<<endl; } int main() { //实例到两个对象 A a("A name","A sex"); B b("B name","B sex",25); //声明一个基类的指针 A* p; //把a对象指针给p p=&a; p->show(); //把b对象指针给p p=&b; p->show(); return 0; }
一个基类A 和一个从A派生出来的类B
A里面有name sex两具属性和一个show方法
B里面有自己的age属性也有一个show方法
实例a,b两个对象
定义一个A类型的指针p,首先把a对象的引用指针设置给p,调用show方法,然后再把b对象的引用指针设置给p,再调用show方法
结果如下:
调用的都是基类A中的show方法,
跟上面描述的结果是一至的。
本来我们把b的引用指针设置给p是想让它使用b的show方法,但结果却并不是我们想要的
下面我们在基类A中把show这个方法声明为虚函数试下,如下
#include <iostream> #include <string> using namespace std; class A { public: A(string n,string s); virtual void show(); protected: string name; string sex; }; A::A(string n,string s){ name=n; sex=s; } void A::show(){ cout<<"A class method: "<<name<<"-->"<<sex<<endl; } //B类继承A类 class B:public A { public: B(string n,string s,int a); void show(); protected: int age; }; B::B(string n,string s,int a):A(n,s){ age=a; } void B::show(){ cout<<"B class method: "<<name<<"-->"<<sex<<"--"<<age<<endl; } int main() { //实例到两个对象 A a("A name","A sex"); B b("B name","B sex",25); //声明一个基类的指针 A* p; //把a对象指针给p p=&a; p->show(); //把b对象指针给p p=&b; p->show(); return 0; }
输出结果如下
这次调用啦b的show方法,也就是说我们用子类的指针设置给啦A(基类)类型的指针变量成功的访问啦子类的方法
在把show改为虚函数前,是无法通过基类指针去调用派生类对象中的成员函数的。虚函数突破了这一限制,在派生类的基类部分中,派生类的虚函数取代了基类原来的虚函数,因此在使基类指针指向派生类对象后,调用虚函数时就调用了派生类的虚函数。 要注意的是,只有用virtual声明了虚函数后才具有以上作用。如果不声明为虚函数,企图通过基类指针调用派生类的非虚函数是不行的。