C++多态相关知识总结

多态

多态是指在不同继承关系的类对象,去调用同一函数,产生了不同的行为。

构成多态的条件:
1.必须通过基类的指针或者引用调用虚函数
2.被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

virtual关键字修饰的类成员函数称为虚函数

虚函数的重写:
派生类中有个函数和基类中的一个函数满足以下条件可以重写函数:
1.函数名相同
2.返回值类型相同
3.参数列表相同
注意:如果基类成员函数前有virtual关键字,而子类成员函数前没有也构成重写。

调用虚函数的类型必须为指针或者引用。如下这样:

class Person {
public:
virtual void BuyTicket() { cout << "买票-全价" << endl; }
}; 

class Student : public Person {
public:
virtual void BuyTicket() { cout << "买票-半价" << endl; }
}; 

void Func(Person& p)  //一般是父类的指针或引用
{
p.BuyTicket();
} 

int main()
{
Person Mike;
Func(Mike);    //使用上边那个函数调用父类虚函数

Student Johnson;
Func(Johnson);   //使用上边那个函数调用子类虚函数

return 0;
} 

函数重写有两个例外:协变 和 析构。

协变:
派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变 。

class A{};
class B : public A {}; 

class Person {
public:
virtual A* f() {return new A;}    //返回基类A的指针
}; 

class Student : public Person {
public:
virtual B* f() {return new B;}   //返回派生类B的指针
}; 

析构:
基类与派生类析构函数的名字不同 ,但编译后析构函数的名称统一处
理成destructor。

final关键字:
修饰虚函数,表示该虚函数不能再被继承

//一般基类函数用,不让子类继承这个函数
virtual void func() final     
{cout << "final" << endl;
} 

override关键字:
检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

//一般子类函数用,看这个函数是否构成重写,没重写就报错
virtual void func() override   
{cout << "override" << endl;
} 

抽象类

在虚函数的后面写上 =0 ,则这个函数为纯虚函数。

包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。

派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。

纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承。

虚表&虚表指针:

只要一个类中有虚函数,那么它里边就还有一个隐藏的成员变量虚表指针

虚表指针指向虚表的首地址,类型是二级指针(函数指针的指针)
一般类的头四个字节就是了。

虚表:存放虚函数指针的数组,类型就是指针数组。
虚表的特点:
1.只存放虚函数的指针,普通成员函数指针不存进来。
2.如果子类没有重写父类任何一个虚函数,则子类直接继承父类的虚表。
3.如果子类重写了父类的一些虚函数,则对应虚函数表里的对应位置的指针就覆盖成子类的虚函数指针。
4.虚表里函数指针的顺序与函数定义/声明的顺序一致。
5.子类有自己新定义的虚函数,则按照声明/定义顺序加到虚函数表的末尾。
6.虚表结尾一般是nullptr。

注意:对象中不存虚表,存的是虚表指针.

虚表指针存在对象中;
虚表存在代码段;
虚函数存在代码段;

动态绑定:
后期绑定,运行时绑定,一般是 继承+虚函数。

静态绑定:
前期绑定,编译时就绑定了,一般是 函数重载,模板。

多继承虚表:

1.继承了几个父类,就有几个虚表。

2.用重写的虚函数的指针替换对应父类虚表中对应的虚函数指针。

3.子类自己新定义的虚函数,按照声明/定义顺序加到第一个继承的父类的虚表的末尾。

多态原理

如果访问虚函数,则通过指针或者引用找到实际指向的实体类,再获取实体类中的虚函数表,通过虚表指针访问虚函数表,在虚函数表中找到想要执行的虚函数指针,再用找到的虚函数指针去执行对应的虚函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值