多态

  • 静态多态
  • 动态多态
  • 模板
  • C++四种类型转换

    多态面向对象语言的三大特征之一,从C++的语言去认识多态。多态简单来说就是相同的函数实现出了不同的效果。

静态多态

静态多态的实现其实就是重载,就是允许函数名称相同但是参数不同的函数存在,这在C语言中是不允许存在的,究其原以是因为C++和C语言的编译规则是不相同的,这也是“extern C”存在的原因。
C++对函数编译的重命名生成符号表时,对参数进行了识别(并没有对返回值进行识别),但C语言只是识别函数名,也就是说C++重载虽然函数名相同,但由于对参数进行了识别,在编译器看来这是不同的函数,也就不会出现重定义的事情存在。
可见静态多态是利用了编译规则实现的,所以它在编译期间就已经确定调用的是谁,所以它被称为静态多态。

动态多态

动态多态大家的第一想到的就是,在共有继承情况下(是is-a的关系),利用虚函数的重写,然后再有父类的指针或者引用去调用,实现根据具体的对象调用相应函数(父类调用父类,子类调用子类),而不是简单依赖类型去识别。
它底层的实现是因为引入了虚表这样一个东西,也就是说如果一个类存在虚函数,这个类就会相应的实现一个存储虚函数的表,类中存储了指向虚表的指针,当子类继承父类时,也会继承其父类的虚表,如果子类对虚函数进行了重写,那么子类的虚函数会覆盖掉原来父类的虚函数(这里的虚函数都指的是指针),当父类的指针和引用去调用虚函数时,会根据具体的指针类型实现调用的具体函数。
这样具体的函数调用在运行时才会被决定,实现出不同的对象调用不同的函数。
建议当析构函数有具体的资源释放时将其设置为虚函数,这样防止内存泄漏。

 Base * a=new Derive();  
 delete a;    //这样的场景下如果析构函数有具体的资源释放,析构函数不是虚函数
        //的情况下,只会释放父类的资源,造成子类自己特有资源的泄漏

但是构造函数(具体的对象都没有生成完全,虚表指针是在生成具体对象时生成)
静态成员函数(属于类不属于某个对象,不能被继承,只属于该类)
内联函数(在编译时已经展开,在函数调用时就已经确定了,虚函数时需要动态绑定的)
最好不要设置为虚函数。
普通函数声明为虚函数没有意义。
备注:
对于上述静态多态和动态多态可以看出,二者的区别是,前者是静态联编,在编译期间就已经确定调用的函数,而后者是在运行时,才知道具体应该调用那个函数,动态联编。

模板

了解C++的都清楚在STL中大量的使用了模板去进行编程,其实模板也可以看作时一种多态,它会根据不同的类型生成不同的代码,但其整体框架在之前就已经确认。
模板是在具体调用时才会具体生成相应的代码。
模板需要注意的是其不能分离编译,具体的可以参照之前的博客。

四种类型转换

其实在C语言中void*可以当初是一个多态,其实我们不关心的它的具体存储,而是用什么样的方式去看待这片内存,比如一个指向int类型的指针,可以强转成char类型的指针,这样是可以的只不过看到的内容变少了,union就是这样的一个例子。但在C语言中任何类型的指针都可以强转,这样太过于BUG,所以C++重新定义了四种类型转换。当然允许类型转换这样的操作存在本身就不是一件安全的事情,所以C++仍然不是类型安全的语言。
reinterpret_cast
支持任何转换,重新解释无视类型信息
b)const_cast
去除指向常量的指针或引用的常量属性
a)static_cast
完成编译器认可的隐式类型转换,但是没有动态的类型检查,是不安全的。
dynamic_cast
与前三者不同的是它实在运行时确定的
使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。
dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。
它转换出的指针或引用一定是可用的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值