cpp多态

什么是多态?
顾名思义就是同一个事物在不同场景下的多种形态

  • 多态
    • 静态多态:编译器在编译期间完成
      • 函数重载
        • 相同的函数名
        • 根据调用参数的不同(参数类型,参数长度),不可根据返回值来判断重载
        • 根据实参类型选择调用合适的函数
          • 合适则调用
          • 不合适则警告或者报错
      • 泛型编程
        • 模板template
    • 动态多态:在程序运行时根据基类的引用或指针 所指向的对象 来确定自己该调用哪一个类的虚函数(因为对象的引用在程序中是变换的,因此是运行时确定)
      • 虚函数
      • 动态多态的条件:
        • 基类中必须包含虚函数,派生类中必须对基类的虚函数进行重写
        • 通过基类(纯虚类)对象的指针或者引用来调用虚函数

如果不是虚函数,那么如果在派生类中出现了与父类同名的函数,那么在即使在使用派生类的对象调用该同名函数时,调用的依然会是父类的;

什么是重写

  • 重写
    • (1)在基类中被派生类重写的函数必须为(纯)虚函数(否则就是产生二义性)
    • (2)重写的函数 在基类和派生类中 的原型 保持一致,协变 和 析构函数除外
      • 原型指:函数返回值类型,函数参数列表,函数名
      • 析构函数名与类名相关
    • (3)访问限定符可以不同

什么是协变?

  • 协变
    • 基类(派生类)的虚函数返回基类(基类)的指针或者引用
//纯虚类 和 纯虚函数
class A{
    virtual void func1() = 0; // 纯虚函数
}
// 有纯虚函数的 类 成为纯虚类,不能创建纯虚类的对象,只能是指针或者引用 ;

class B:public A{
    void fun2();
}
// B继承了A,但是并没有实现基类A中的纯虚函数,因此B也是纯虚类

class C:public:A{
    void func1(){
        ///codes
    }
}
// C继承了A,并实现基类A中的纯虚函数,因此C不是纯虚类
  • 哪些函数不能定义为虚函数
    • 友元函数,因为它不属于类的成员函数
    • 全局函数
    • 静态成员函数,因为它没有this指针
    • 构造函数,拷贝构造函数(**)
    • 运算符重载函数可以,但是一般不建议

(**):
类包含虚函数时,编译器在编译期为该类型生成虚函数表;

在类的对象创建时,编译器为该对象生成一个指向虚函数表的 虚函数指针( PVFT* 4 Byte)

虚函数指针的初始化是在构造函数中完成的;

因此,不能将构造函数定义为虚函数 virtual

纯虚类

  • 抽象类(纯虚类)
    • 也称为 接口类
    • 包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。
    • 抽象类一定要被继承,否则无意义

那么派生类的虚函数表怎么做的:

  • 派生类虚表:
    • 1.先将基类的虚表中的内容拷贝一份
    • 2.如果发生了重写,使用派生类的虚函数替换相同偏移量位置的基类虚函数
    • 3.如果派生类中新增加自己的虚函数,按照其在派生类中的声明次序,放在上述虚函数之后

多态优点:
●代码组织结构清晰
●可读性强
●利于前期和后期的扩展以及维护 对拓展开放,对修改关闭

多态缺陷:
●降低了程序运行效率(多态需要去找虚表的地址)
●空间浪费(虚函数指针)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值