五.虚函数与多态
1.多态性,就相当于一个函数名(在基类和派生类中),多种意思表达;也可以是界面相同,实现方式不同。
重载函数就是多态性的一种体现。
2.虚函数,前面加关键字virtual的成员函数就是虚函数。这是实现多态的前提,然后用指针调用派生类不同实现版本
基类指针只可以访问派生类从基类中继承下来的成员
以一个例子为例:
#include<bits/stdc++.h>
using namespace std;
class base
{
public:
base(char aa):a(aa){}
void show(){cout<<"base: "<<a<<endl;};
protected:
char a;
};
class derive1:public base//基类为base;
{
public:
derive1(char aa,char bb):base(aa){b=bb;}
void show(){cout<<"derive1: "<<b<<endl;};
protected:
char b;
};
int main()
{
base a('1');
derive1 b('1','2');
base *p;
p=&a;
p->show();
p=&b;
p->show();//想让他输出2
}
可是运行结果都只是输出1
如果加以改变,在基类的show函数前面冠以virtual,结果就会如我们所想
需要注意的是
参数类型和顺序完全相同
3.虚析构函数
普通基类和派生类析构函数调用情况是
基类析构函数前冠以voirtual后
一般通过基类指针访问虚函数时才能体现多态性;
例如上课时的一个例子
#include <iostream>
using namespace std;
class A
{ public:
virtual double funA(double x)
{ cout<<"funA of class A called."<<endl;
return x*x; }
double funB(double x)
{ return funA(x)/2; }
};
class B:public A
{ public:
virtual double funA(double x)
{ cout<<"funA of class B called."<<endl;
return 2*x*x; }
};
class C:public B
{ public:
virtual double funA(double x)
{ cout<<"funA of class C called."<<endl;
return 3*x*x;
}
};
int main()
{
C objc;//调用基类FUN
cout<<objc.funB(3)<<endl;//基类中调用的FUNA是C类中的。3*3*3/2=13.5
B objb;
cout<<objb.funB(3)<<endl;2*3*3/2;=9
}
4.纯虚函数
例如
class figure
{ protected : double x,y;
public: void set_dim(double i, double j=0) { x = i ; y = j ; }
virtual void show_area() = 0 ;
/*
在基类中,并不写函数原型,只定义,格式为 virtual +返回值类型+函数名+=0;
在后面的各个派生类中,定义不同的内容,实现不同的功能。
*/
};
class triangle : public figure
{ public :
void show_area()
{ cout<<"Trianglewith high "<<x<<" and base "<<y <<"has an area of "<<x*0.5*y<<"\n"; }
};
class square : public figure
{ public:
void show_area()
{ cout<<"Squarewith dimension "<<x<<"*"<<y <<" hasan area of "<<x*y<<"\n"; }
};
class circle : public figure
{ public:
void show_area()
{ cout<<"Circlewith radius "<<x;
cout<<"has an area of "<<3.14*x*x<<"\n";//
//即函数名称相同,但具体意义不同;
}
};