虚函数与多态:
如果将基类中的成员函数声明为虚函数,那么子类中可以重写基类中该虚函数(子类中无论是否有virtual关键字都是虚函数),这样对积累中的虚函数形成覆盖
这时,通过一个基类类型的指针指向子类对象时,或者通过一个基类类型的引用引用子类对象时,调用该虚函数时,实际被调用的函数不由指针或者引用本身的类型决定,而是由它们的目标对象来决定,最终导致子类覆盖版本的函数被调用,这种现象称为多态
#include <iostream>
using namespace std;
class Shape{
private:
public:
//平面图形所在坐标位置
int x;
int y;
public:
Shape(int x=0,int y=0):x(x),y(y){}
void show(){
cout << "(" << x << "," << y << ")" << endl;
}
virtual double len(){
cout << "shape" << endl;
return 0.0;
}
virtual double area(){
cout << "shape" << endl;
return 0;
}
};
//长方形类
class Cube:public Shape{
private:
public:
int l;
int w;
public:
Cube(int l,int w,int x,int y):Shape(x,y),l(l),w(w){}
double len(){
cout << "Cube" << endl;
return 2*(l+w);
}
double area(){
cout << "Cube" << endl;
return l*w;
}
};
//圆形类
class Circle:public Shape{
private:
public:
int r;
public:
Circle(int r,int x,int y):Shape(x,y),r(r){}
double len(){
cout << "Circle" << endl;
return 3.14*2*r;
}
double area(){
cout << "Circle" << endl;
return 3.14*r*r;
}
};
int main(){
Shape *ps = new Cube(2,4,0,0);//指针类型为Shape类型,实际调用的是Cube类型的函数
cout << ps->len() << endl;
cout << ps->area() << endl;
delete ps;
Cube c(2,5,1,1);
Shape& rc = c;
cout << rc.len() << endl;
cout << rc.area() << endl;
ps = new Circle(5,1,1);
cout << ps->len() << endl;
cout << ps->area() << endl;
return 0;
}
多态:虚函数/覆盖 + 指针/引用
覆盖 override
重载 overload
同一个作用域下,函数名相同,参数列表不同即构成重载
覆盖 override
子类重写父类同型的虚函数 除去重载和覆盖才是隐藏
隐藏 hide
子类隐藏父类同名的标识符
怎样才能形成覆盖?覆盖的条件:
1.形成覆盖函数,在基类中必须是虚函数
2.子类中函数名、形参列表、常属性必须严格一致
参数列表、普通类型或者对象 常属性可以不一样,不影响
但如果是指针或者引用,参数的常属性必须相同
3.返回值:
如果函数返回的类型为基本类型或者对象,那么必须严格一致
如果返回的是类类型的指针或者类类型的引用,那么子类版本的返回值可以基类版本返回值类型的子类类型的指针和引用
class A{};
class B:public A{};
class C{
cirtual A*func(){}
}
class D:public C{
B* func(){}//覆盖
}
4.子类的覆盖版本不能比基类版本声明更多的异常抛出
5.子类覆盖版本的访问控制属性不受基类版本的限制,即使父类中为私有的虚函数,子类版本中也可以覆盖
#include <iostream>
using namespace std;
class A{
public:
void f1(){
cout << "A f1()" << endl;
}
virtual void f2(){
cout << "A f2()" << endl;
}
virtual void f3(int x){
cout << "A f3(int)" << endl;
}
virtual void f4(const int& x){
cout << "A f4()" << endl;
}
virtual void f5(int x)const{
cout << "A f5()" << endl;
}
};
class B:public A{
public:
void f1(){//隐藏
cout << "B f1()" << endl;
}
void f2(){
cout << "B f2()" << endl;
}
void f3(){//隐藏
cout << "B f3()" << endl;
}
virtual void f4(int& x){//参数引用 常属性不一样 不会构成覆盖
cout << "B f4()" << endl;
x = 111;
}
void f5(int x){//常属性不一样 不会构造覆盖
cout << "B f5() " << endl;
}
};
int main(){
A* p = new B;
p->f1();
p->f2();
int x = 1;
p->f4(x);
p->f4(1);
p->f5(x);
B b;
b.f1();
b.f3();//B
b.A::f3(1);//A
return 0;
}
