C++|多态性

什么是多态

接口有多种形态,能根据操作环境的不同采用不同的处理方式

编译时多态(静态绑定)

shape *ps;//静态类型shape*
shape *ps=new circle;//静态类型shape*

作用: 根据类型匹配等特征确定某一个同名函数到底是要调用哪一段函数
原理: 代码中声明的类型=对象的静态类型
通过: 函数重载/运算符重载

  • 基类指针指向派生类,调用时仍然是基类函数
gstudent s2;//子类对象声明
ps=& s2;//!!基类指针可以指向派生类对象!!
ps->print();//因为未通过虚函数等动态绑定方法,所以此处为静态绑定(编译时多态)故编译器不知道派生类有重名函数,仍用基类函数

运算符重载

功能: 给已有运算符新的功能,使面对不同类型的数据有不同的行为(代替原来的函数功能)
实质: 函数重载
已预定义的运算符: 自动调用运算符函数operator+(i,j)
不能重载的运算符: “.” “*” “::” “?:”
重载方式:

  • 类的非静态成员函数(有this指针)
  •  () [] newdelete只能用此方式重载
    
  • 友元函数(无this指针)

前置/后置运算符

clock& operator++();//前置,没有形参
相当于
a.operator++();

clock operator++(int);//后置,有形参
相当于
a.operator++(0);
  •  后置运算符作类成员函数时 z+1->z.operator(1),1满足int 但1+z->1.operator(z),z不知是否满足->不支持交换律
    

对输出<<的重载

friend complex &operator<<(ostream& out, const complex& c);//输出<<友元重载,参数为os类的out对象
(省略)
ostream& operator<<(ostream& out, const complex& c) {
	out << "(" << c.real << "," << c.imag << ")";//对输出格式的扩展
}
  • 即代替了原来的display()函数
void complex::display()const {
	cout << "(" << real << "+" << imag << "i)" << endl;//(a+bi)格式输出
}
(省略)
cout << "c1=";
c1.display();

对赋值=的重载

three_d & operator=(three_d & t);
three_d& three_d::operator=(three_d& t) {//3d类型的引用,用&,使*this有地址存放
	x = t.x;
	y = t.y;
	z = t.z;
	return *this;//与&对应,
}
  • 只能是成员函数,不能友元
  • 用于对已有对象改变其值,而复制构造函数用于创建一个新对象

运行时多态(动态绑定)

通过: 继承/虚函数
原理: 由运行时对象当前所指的对象类型决定,对象的动态类型表示它将执行何种行为。

shape *ps;//不指向任何对象,没有动态类型
shape *pc=new ciecle;//动态类型circle*
shape *pr=new rectangle;//动态类型rectangle*
改变动态类型:赋值
ps=pc;//ps的动态类型由无到circle*

虚函数

功能:

  • 派生类可以重写基类中的虚函数,实现自己的功能

哪些不能做虚函数

  • 非成员函数
  • 构造函数
  • 内联inline成员函数(∵编译时就被展开)
  • 静态成员函数(本来就被所有对象共享)
  • 友元函数(没有继承特性,就没有虚函数之说)

编译?运行?:
1、对象名.虚函数()->编译时多态
2、成员函数里调用虚函数->运行时多态
3、指针->虚函数->运行时多态

  • 通过基类指针/引用调用才会动态绑定->各调用各自
  •   因为基类指针可以指向派生类的对象,基类引用可以作为派生类对象的别名;反之不行
    
display在基类已声明为虚函数
void fun(base*ptr){//形参是指向基类的指针
	ptr->display();//函数调用虚成员函数
}

base b;
derived d;
fun(&b);//基类display
fun(&d);//派生类display
  • 通过派生类指针可以通过base::限定使输出总是基类display
void fun(derived* ptr) {//形参是指向派生类的指针,实参不能是基类对象
	ptr->base::display();//加基类base限定,总会调用基类display
}
derived d;
fun(&d);//基类display

  • 构造/析构函数调用虚函数: 只会调用派生类的虚函数

纯虚函数

是: 一个类中没有实现的函数,在派生类实现后 就不再是纯虚函数
用于: 基类不用声明具体功能,由各个派生类自己定义
声明:

virtual 函数类型 函数名(参数表)=0//多了后面=0

对象切片

用派生类对象复制构造基类对象

derived d;//子类
base*ptr=&d;//
base&ref=d;
base b=d;//虽然是子类d赋值给b,但是调用的是base的复制构造函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值