多态与继承_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.被重写的虚函数即可表现多态的特性。

原文地址:https://www.cnblogs.com/lvxiaoning/p/7650359.html