zoukankan      html  css  js  c++  java
  • 第49课 多态的概念和意义

    上一节中,函数重写遇上赋值兼容出现了问题:

    34、35行调用的都是父类中的print函数。

    35行我们给的实参是Child对象,期望调用子类中的print函数,但是运行结果并不是这样。

    函数重写回顾:

    子类中重定义父类中已有的函数,就是因为父类中的函数满足不了我们的需求。

    我们期望的是只要是子类对象,调用的都是子类中的函数版本。

    即使将子类对象赋值给父类指针或者引用,调用同名函数时我们也期望调用的是子类中的版本。

    多态的概念和意义:

    多态:

    示例程序:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Parent
     7 {
     8 public:
     9     virtual void print()
    10     {
    11         cout << "I'm Parent." << endl;
    12     }
    13 };
    14 
    15 class Child : public Parent
    16 {
    17 public:
    18     void print()
    19     {
    20         cout << "I'm Child." << endl;
    21     }
    22 };
    23 
    24 void how_to_print(Parent* p)
    25 {
    26     p->print();     // 展现多态的行为
    27 }
    28 
    29 int main()
    30 {
    31     Parent p;
    32     Child c;
    33     
    34     how_to_print(&p);    // Expected to print: I'm Parent.
    35     how_to_print(&c);    // Expected to print: I'm Child.
    36     
    37     return 0;
    38 }

    第9行加上了virtual,这就是告诉编译器,这个函数在子类中有可能被重写。得考虑是不是要展现多态的行为。

    编译器在遇到virtual就会做特殊的处理。

    第18行的程序没有写virtual关键字,但是由于继承的关系,它就是virtual的,这里可写可不写。

    运行结果如下:

    多态的意义:

    多态在编译时无法知道要调用哪一个函数,是在运行时决定的。

    但凡发生函数重写,那么被重写的函数必然的是virtual的,因为我们需要多态,要不然我们也不会重写。

    理论概念:

     动态联编与静态联编:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Parent
     7 {
     8 public:
     9     virtual void func()
    10     {
    11         cout << "void func()" << endl;
    12     }
    13     
    14     virtual void func(int i)
    15     {
    16         cout << "void func(int i) : " << i << endl;
    17     }
    18     
    19     virtual void func(int i, int j)
    20     {
    21         cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;
    22     }
    23 };
    24 
    25 class Child : public Parent
    26 {
    27 public:
    28     void func(int i, int j)
    29     {
    30         cout << "void func(int i, int j) : " << i + j << endl;
    31     }
    32     
    33     void func(int i, int j, int k)
    34     {
    35         cout << "void func(int i, int j, int k) : " << i + j + k << endl;
    36     }
    37 };
    38 
    39 void run(Parent* p)
    40 {
    41     p->func(1, 2);     // 展现多态的特性
    42                        // 动态联编
    43 }
    44 
    45 
    46 int main()
    47 {
    48     Parent p;
    49     
    50     p.func();         // 静态联编
    51     p.func(1);        // 静态联编
    52     p.func(1, 2);     // 静态联编
    53     
    54     cout << endl;
    55     
    56     Child c;
    57     
    58     c.func(1, 2);     // 静态联编
    59     
    60     cout << endl;
    61     
    62     run(&p);
    63     run(&c);
    64     
    65     return 0;
    66 }

    同名覆盖只能发生在父类和子类之间。

    运行结果如下:

     示例程序:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 class Boss
     7 {
     8 public:
     9     int fight()
    10     {
    11         int ret = 10;
    12         
    13         cout << "Boss::fight() : " << ret << endl;
    14         
    15         return ret;
    16     }
    17 };
    18 
    19 class Master
    20 {
    21 public:
    22     virtual int eightSwordKill()
    23     {
    24         int ret = 8;
    25         
    26         cout << "Master::eightSwordKill() : " << ret << endl;
    27         
    28         return ret;
    29     }
    30 };
    31 
    32 class NewMaster : public Master
    33 {
    34 public:
    35     int eightSwordKill()
    36     {
    37         int ret = Master::eightSwordKill() * 2;
    38         
    39         cout << "NewMaster::eightSwordKill() : " << ret << endl;
    40         
    41         return ret;
    42     }
    43 };
    44 
    45 void field_pk(Master* master, Boss* boss)
    46 {
    47     int k = master->eightSwordKill();
    48     int b = boss->fight();
    49     
    50     if( k < b )
    51     {
    52         cout << "Master is killed..." << endl;
    53     }
    54     else
    55     {
    56         cout << "Boss is killed..." << endl;
    57     }
    58 }
    59 
    60 int main()
    61 {
    62     Master master;
    63     Boss boss;
    64     
    65     cout << "Master vs Boss" << endl;
    66     
    67     field_pk(&master, &boss);
    68     
    69     cout << "NewMaster vs Boss" << endl;
    70     
    71     NewMaster newMaster;
    72     
    73     field_pk(&newMaster, &boss);
    74     
    75     return 0;
    76 }

    运行结果如下:

    小结:

  • 相关阅读:
    数据库系列之T-SQL(系统内置函数)
    数据库系列之T-SQL(存储过程)
    数据库系列之T-SQL(作业与维护计划)
    数据库系列之T-SQL(触发器)
    数据库系列之T-SQL(事务)
    数据库系列之T-SQL(基础)
    数据库系列之查询(5)
    Nginx + Apache 公用80端口的配置
    客户端putty, xshell连接linux中vim的小键盘问题
    配置EPEL YUM源
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9575643.html
Copyright © 2011-2022 走看看