zoukankan      html  css  js  c++  java
  • 多态与继承_16

    一。函数重写

      1.在子类中定义与父类中原型相同的函数

      2.函数重写只发生在父类与子类之间

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    
    class Parent
    {
        public:
            void Print()
            {
                cout << "Parent()" << endl;    
            }
    
    };
    
    class Child : public Parent
    {
        public:
            void Print()
            {
                cout <<"Child()"<< endl;    
            }
    };
    
    void run()
    {
        Child child;
        child.Print();
    }
    
    int main(int argc, char *argv[])
    {
        run();
        
        cout << "Press the enter key to continue ...";
        cin.get();
        return EXIT_SUCCESS;
    }

      3.父类中被重写的函数依然会继承给子类

      4.默认情况下子类的重写函数会掩藏父类的函数

      5.通过作用域分辨符::可以访问到父类中被隐藏的函数

    二。当函数重写遇上了赋值兼容性原则

    void run()
    {
        Child child;
        Parent* pp = &child;
        Parent& rp = child;
        
        child.Print();
        pp -> Print();
        rp.Print();
    }

    问题所在:

      1.在C++和C相同,是静态编译型语言

      2.在编译时,编译器自动根据指针的类型判断指向是一个什么样的对象

      3.所以编译器认为父类指针是指向的父类对象(根据赋值兼容性原则,则这个假设合理)

      4.由程序没有执行,所以不知道父类指针指向的具体是父类对象还是子类对象

      5.从程序安全的角度,编译器假设父类指针只指向父类对象,因此编译的结果为调父类的成员函数。

    三。多态的本质

      1.面向对象的新需求

       a.根据实际的对象类型来判断重写函数的调用

       b.父类对象指向父类的函数。

      2.面向对象中的多态:

        根据实际的对象类型决定函数调用语句的具体调用目标

      3.c++中通过virtual 关键字对多态进行支持

        使用virtual声明的函数被重写后即可展现多态特性 - 这就是传说中的虚函数

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    class Boss
    {
    private:
        static Boss* cInstance;
        
        Boss()
        {
        }
    public:
        static Boss* GetInstance()
        {
            if( cInstance == NULL )
            {
                 cInstance = new Boss();
            }
            
            return cInstance;
        }
        
        int fight()
        {
            cout<<"Boss::fight()"<<endl;
            return 10;
        }
    };
    
    Boss* Boss::cInstance = NULL;
    
    class Master
    {
    public:
        virtual int eightSwordKill()
        {
            cout<<"Master::eightSwordKill()"<<endl;
            return 8;
        }
    };
    
    class NewMaster : public Master
    {
    public:
        virtual int eightSwordKill()
        {
            cout<<"NewMaster::eightSwordKill()"<<endl;
            return Master::eightSwordKill() * 2;
        }
    };
    
    void fieldPK(Master* master, Boss* boss)
    {
        int k = master->eightSwordKill();
        int b = boss->fight();
        
        if( k < b )
        {
            cout<<"Master is killed..."<<endl;
        }
        else
        {
            cout<<"Boss is killed..."<<endl;
        }
    }
    
    int main(int argc, char *argv[])
    {
        Boss* boss = Boss::GetInstance();
        
        cout<<"Master vs Boss"<<endl;
        
        Master master;
        
        fieldPK(&master, boss);
        
        cout<<"New Master vs Boss"<<endl;
        
        NewMaster newMaster;
        
        fieldPK(&newMaster, boss);
        
        cout << "Press the enter key to continue ...";
        cin.get();
        return EXIT_SUCCESS;
    }

    四。小结

      1.函数重写是面向对象中很可能发生的情形

      2.函数重写只可发生在父类和子类之间

      3.需要根据实际对象的类型确定调用的具体函数

      4.virtual 关键字是c++中支持多态的唯一方式

      5.被重写的虚函数即可表现多态的特性。

  • 相关阅读:
    第三章:Hadoop简介及配置Hadoop-1.2.1,hbase-0.94.13集群
    maven环境的搭建,lemon-OA办公系统的搭建
    如何打开mo文件并修改 PoEdit
    安装Elastix-2.4版本
    RabbitMQ安装
    Yum编译安装Error Downloading Packages报错
    linux:ping不通www.baidu.com
    tar命令解压缩出错
    PV、UV
    使用存储过程创建数据
  • 原文地址:https://www.cnblogs.com/lvxiaoning/p/7650359.html
Copyright © 2011-2022 走看看