1 静态多态
实现
函数重载,在编译器确定
函数重载的条件:
- 函数名相同
- 参数个数不同,参数的类型不同,参数顺序不同
- 返回值类型,不作为重载的标准
原理
函数名修饰(替换),进行命名倾轧
函数执行过程:
- 预处理 :把头文件的函数声明拷贝到源文件
- 编译 : 语法分析,同时进行函数汇总
- 汇编 :生成函数名到函数地址的映射
- 链接 : 加那个多个文件的符号表汇总合并
2 动态多态
实现
多态实现条件:
- 父类中有虚函数,即共用接口
- 子类 override(覆写)父类中的虚函数
- 通过己被子类对象赋值的父类指引用 或子类对象地址赋值给父类指针,调用共用接口
虚函数声明:
class 类名
{
virtual 函数声明;
}
纯虚函数:
- 纯虚函数只有声明,没有实现,被“初始化”为 0
- 含有纯虚函数的类,称为 Abstract Base Class(抽象基类),不可实例
声明:
class 类名
{
virtual 函数声明 = 0;
}
原理
若类使用虚函数,则会为类生成虚函数表(一维数组,存放了虚函数表的地址),类对象构造时会初始化虚函数表的指针
code
#include <iostream>
using namespace std;
class Shape
{
public:
Shape(int x,int y)
:_x(x),_y(y){}
virtual void draw()
{
cout<<"draw Shap ";
cout<<"start ("<<_x<<","<<_y<<") "<<endl;
}
protected:
int _x;
int _y;
};
class Circle:public Shape
{
public:
Circle(int x, int y,int r)
:Shape(x,y),_r(r){}
void draw()
{
cout<<"draw Circle ";
cout<<"start ("<<_x<<","<<_y<<") ";
cout<<"raduis r = "<<_r<<endl;
}
private:
int _r;
};
int main()
{
Shape s(3,5);
Circle c(1,2,4);
// 不能实现多态
s = c;
s.draw();
// 子类对象赋值为父类引用,实现多态
Shape &rs = c;
rs.draw();
//子类对象地址赋值给父类指针,实现多态
Shape *ps = &c;
ps->draw();
return 0;
}
运行结果:
draw Shap start (1,2)
draw Circle start (1,2) raduis r = 4
draw Circle start (1,2) raduis r = 4