基础备忘:多态的实现(重载、虚函数、抽象类)

1.函数重载由静态联编支持的多态性称为编译时的多态性或静态多态性,也就是说,确定同名操作的具体操作对象的过程是在编译过程中完成的。在C++中,可以用函数重载和运算符重载来实现编译时的多态性。2.虚函数由动态联编支持的多态性称为运行时的多太性或动态多态性,也就是说,确定同名操作的具体操作对象的过程是在运行过程中完成的。在C++中,可以用虚函数来实现运行时的多态性。2.1.虚函数定义
摘要由CSDN通过智能技术生成

1.函数重载

由静态联编支持的多态性称为编译时的多态性或静态多态性,也就是说,确定同名操作的具体操作对象的过程是在编译过程中完成的。在C++中,可以用函数重载和运算符重载来实现编译时的多态性。

2.虚函数

由动态联编支持的多态性称为运行时的多太性或动态多态性,也就是说,确定同名操作的具体操作对象的过程是在运行过程中完成的。在C++中,可以用虚函数来实现运行时的多态性。

2.1.虚函数定义

虚函数的定义是在基类中进行的,即把基类中需要定义为虚函数的成员函数声明为virtual。当基类中的某个成员函数被声明为虚函数后,就可以在派生类中被重新定义。在派生类中重定义时,其函数原型,包括返回类型、函数函数名、参数个数和类型、参数的顺序都必须与基类中的原型完全一致

定义形式为:

virtual <函数类型><函数名>(参数表)

{

函数体

}

例如:解决博文多态概念时的问题代码如下:

#include<iostream>
using namespace std;
class Animal
{
      public:
             void sleep()
             {
                  cout<<"Animal Sleep"<<endl;
                  }
            virtual void breathe()//加上virtual 
             {
                  cout<<"Animal Breathe"<<endl;
                  }
      };
class Fish:public Animal
{
      public:
             void breathe()
             {
                  cout<<"Fish Bubble"<<endl;
                  }
      };
int main()
{
    Fish fs;
    Animal *an=&fs;
    an->breathe();
    system("pause");
    }

只是加了一个virtual问题就解决了。输出结果为:

事实上,当将基类中的成员函数breathe()声明为virtual即虚函数时,编译器在编译的时候发现Animal类中有虚函数,此时编译器会为每个包含虚函数的类创建一个虚表,该表是一个一维数组,在这个数组中存放每个虚函数的地址。上述代码中,Animal类和Fish类都包含了一个虚函数breathe(),因此编译器会为这两个类分别建立一个虚表,如下图所示。

类Animal和类Fish的虚表

在上述代码中,当Fish类的fs对象构造完毕后,其内部的虚表指针也就被初始化为指向Fish类的虚表。在转换后,调用an->breathe(),由于an实际指向的是Fish类的对象,该对象内部的虚表指针指向的是Fish类的虚表,因此最终调用的是Fish类的breathe()函数。

使用派生对象指针时应注意的问题:

1.声明为指向基类对象的指针可以指向它的公有派生类的对象,但不允许指向它的私有派生类的对象。

2.允许声明为指向基类对象的指针指向它的公有派生类的对象,但不允许将一个声明为指向派生类对象的指针指向基类的对象。

3.声明为指向基类对象的指针,当其指向它的公有派生类的对象时(满足第1条),只能直接访问派生类中从基类继承下来的成员,不能直接访问公有派生类中定义的成员。要想访问其公有派生类中的成员,可将基类指针用显式类型转换方式转换为派生类指针。例如:

#include<iostream>
using namespace std;
class B
{
      public:
             void vf()
             {
                  cout<<"This is class B"<<endl;
                  }
      };
class D:public B
{
      public:
             void vf()
             {
                  cout<<"This is class D"<<endl;
                  }
      };
int main()
{
    B b,*pb;
    D d,*pd;
    pb= &b;
    pb->vf();
    pb=&d;//满足第1第2条。 
    pb->vf();
 // pd=&b;//违背第2条。invalid conversion from `B*' to `D*' 
 // pd->vf();
    pd=(D*)&b;//满足第3条。 
    pd->vf();
    pd=&d;
    pd->vf();
    system("pause");
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值