• C++面向对象笔记:多态


    从系统实现的角度看,多态性分为两种,静态多态性与动态多态性

    静态多态性:函数重载、运算符重载(本质上也是函数重载);

    动态多态性:在程序运行过程中才动态地确定操作所针对的对象,又称为运行时的多态性,一般通过虚函数(virtual function)实现。

    C++通过虚函数与指向基类的指针一起来实现多态

    1. 当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数,因此在派生类中重新声明该虚函数时,可以加virtual,也可以不加,但最好加virtual,使程序清晰。
    2. 如果在派生类中没有对基类中的虚函数重新定义,则派生类继承其直接基类的虚函数。

    静态关联:在编译时即可确定其调用的虚函数属于哪一个类,如函数重载与通过对象名调用的虚函数

    动态关联:在运行阶段把虚函数和类对象绑定在一起

    何时申明虚函数

    1. 首先成员函数所在的类是否会作为基类,其次成员函数在类的继承后有无可能被更改功能,如果希望更改其功能的,一般要设为虚函数
    2. 如果成员函数在类被继承后功能不需要修改,或派生类用不到该函数,则不要把它设为虚函数
    3. 考虑对成员函数的调用时通过对象名还是基类指针或者引用,若是通过基类指针或引用去访问,则应设为虚函数
    4. 有时,在定义虚函数时,并不定义函数体(其函数体是空的),只是定义了一个虚函数名,具体功能留给派生类去添加。

    使用虚函数,系统有一定的空间开销,当一个类有虚函数时,系统会为该类构造一个虚函数表(一个指针数组,存放每个虚函数的入口地址)

    若一个类中有虚函数,则实例化该类时,对象的第一个成员将是一个指向虚函数表的指针。

    纯虚函数,抽象类

    virtual int f() = 0;//声明纯虚函数

    若一个类中有纯虚函数,则该类为抽象类,抽象类不能实例化,只能用作继承基类

    View Code
     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 //定义基类-动物类
     6 class Animals
     7 {
     8 public:
     9     Animals();//定义构造函数
    10     Animals(int);//带一个参数的构造函数
    11 public:
    12     int id;
    13 public:
    14     virtual void Action();//定义成员函数吗,声明为虚函数,用以实现多态
    15 };
    16 
    17 Animals::Animals(){}//实现构造函数
    18 Animals::Animals(int id):id(id){}//实现构造函数,初始化成员列表在定义时不指定,函数实现时才指定
    19 void Animals::Action()//实现成员函数
    20 {
    21     cout<<"Animal's action"<<endl;
    22 }
    23 
    24 
    25 //定义派生类-人类
    26 class Person:public Animals
    27 {
    28 public:
    29     Person(int,int,int);//定义构造函数,实现时才调用父类构造函数
    30 public://成员变量
    31     int weight;//体重
    32     int height;//身高
    33 public://成员函数
    34     virtual void Action();//定义成员函数吗,声明为虚函数,用以实现多态
    35 };
    36 //实现派生类构造函数,并显示调用基类构造函数
    37 Person::Person(int weight,int height,int id):Animals(id)
    38 {
    39     this->weight = weight;
    40     this->height = height;
    41 }
    42 
    43 //实现派生类成员函数
    44 void Person::Action()
    45 {
    46     cout<<"person's action: walk"<<endl;
    47 }
    48 
    49 //定义派生类-猴类
    50 class Monkey:public Animals
    51 {
    52 public:
    53     Monkey(int,int,int);//定义构造函数,实现时才调用父类构造函数
    54 public://成员变量
    55     int weight;//体重
    56     int height;//身高
    57 public://成员函数
    58     virtual void Action();//定义成员函数吗,声明为虚函数,用以实现多态
    59 };
    60 //实现派生类构造函数,并显示调用基类构造函数
    61 Monkey::Monkey(int weight,int height,int id):Animals(id)
    62 {
    63     this->weight = weight;
    64     this->height = height;
    65 }
    66 
    67 //实现派生类成员函数
    68 void Monkey::Action()
    69 {
    70     cout<<"monkey's action: jump"<<endl;
    71 }
    72 
    73 int main()
    74 {
    75     //定义动物类对象
    76     Animals a;
    77     //定义动物类指针
    78     Animals * pi;
    79     pi = &a;
    80     //通过指针调用行为
    81     pi->Action();
    82     Person b(10,10,0001);
    83     pi = &b;//改变指针指向person
    84     pi->Action();
    85     Monkey c(10,10,0002);
    86     pi = &c;//改变指针指向monkey
    87     pi->Action();
    88     return 0;
    89 }
  • 相关阅读:
    LeetCode—-Sort List
    LeetCode——Longest Consecutive Sequence
    LeetCode——single-number系列
    freeswitch源码阅读 之 sofia模块
    freeswitch 内核模块开发
    FreeSwitch B2B 状态转换流程
    freeswitch嵌入python脚本
    freeswitch注册过程分析
    freeswitch对接其它SIP设备
    freeswitch模块之event_socket
  • 原文地址:https://www.cnblogs.com/jiese/p/2573888.html
Copyright © 2020-2023  润新知