C++多态概念和意义

目录

一、什么叫重写

二、面向对象期望的重写​

1、示例分析

2、所期望的重写

三、多态的概念和意义

1、多态的概念

2、C++如何支持多态概念

3、多态内部运行剖析

4、多态的意义

5、修改示例代码

四、静态联编和动态联编

五、小结


一、什么叫重写

1、子类中可以重定义父类中已经存在的成员函数;

2、这种重定义发生在继承中,叫做函数重写;

3、函数重写是同名覆盖的一种特殊情况。

C++多态概念和意义_第1张图片

二、面向对象期望的重写

先来验证个小示例:

#include 
#include 
#include 

using namespace std;

class Parent
{

public:

    void Printfln()
    {
        std::cout << "Parent: void Printfln()..." << std::endl;
    }
};

class Child : public Parent
{
public:

    void Printfln()
    {
        std::cout << "Child: void Printfln()..." << std::endl;
    }
};

void run(Parent *p)
{
    p->Printfln();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Parent p;
    Child c;

    run(&p);
    run(&c);

    return a.exec();
}

1、示例分析

1、结果:结果是调用两次run函数打印的结果相同;

2、分析:

(1)编译期间,编译器只能根据指针的类型判断所指向的对象;

(2)根据赋值兼容性原则,编译器认为父类指针指向的是父类对象;

(3)run函数中的指针p,编译器不可能知道它指向的究竟是什么,但是编译器没理由报错,编译器认为最安全的做法就是调用父类Printfln()函数,因为父类和子类都有相同的Printfln()函数;

(4)因此,编译器结果只可能是调用父类定义的同名函数。

2、所期望的重写

面向对象的期望重写行为:根据实际的对象类型来判断如何调用重写函数

(1)当父类指针(引用)指向父类对象,则调用父类中定义的成员函数;

(2)当父类指针(引用)指向子类对象,则调用子类中定义的重写函数。

三、多态的概念和意义

1、多态的概念

(1)根据实际的对象类型决定函数调用的具体目标;

(2)同样的调用语句在实际运行时有多种不同的表现形态体现,这就是多态,同一语句具有多种形态。

C++多态概念和意义_第2张图片

2、C++如何支持多态概念

(1)通过使用virtual关键字对多态进行支持;

(2)被virtual修饰的函数被重写后具有多种不同的表现形态;

(3)被virtual声明的函数称为虚函数。

3、多态内部运行剖析

父类和子类的对象,首地址都各自有一个虚函数表地址,该地址都保存着虚函数Printfln()的地址,在运行过程中

(1)在父类指针(引用)p,指向父类对象,就相当于指向父类的虚函数表,从而在父类的虚函数表中找到Printfln()函数;

(2)在父类指针(引用)p,指向子类对象,相当于指向子类的虚函数表,从而在子类的虚函数表中找到Printfln()函数。

C++多态概念和意义_第3张图片

4、多态的意义

(1)在程序运行中展现出动态的特性;

(2)函数重写必须多态实现,否则没有任何意义;

(3)多态是面向对象组件化程序设计的基础特性。

5、修改示例代码

根据多态的概念,在程序中给父子类同名函数声明virtual关键字,只需要在父类中声明即可,在子类中可以不写,写了也是对的,编译器不会报错。

#include 
#include 
#include 

using namespace std;

class Parent
{

public:

    virtual void Printfln()
    {
        std::cout << "Parent: void Printfln()..." << std::endl;
    }
};

class Child : public Parent
{
public:

    void Printfln()
    {
        std::cout << "Child: void Printfln()..." << std::endl;
    }
};

void run(Parent *p)
{
    p->Printfln();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Parent p;
    Child c;

    run(&p);
    run(&c);

    return a.exec();
}

四、静态联编和动态联编

1、静态联编:程序编译期间就能确定的具体的函数调用,如函数重载;

2、动态联编:程序运行期间才能确定的具体的函数调用,如函数重写。

五、小结

1、函数重写只能发生在父类和子类之间;

2、多态是根据实际对象类型确定调用具体的函数;

3、virtual关键字是C++支持多态的唯一方式;

4、被重写的虚函数具有多种不同表现形态。

你可能感兴趣的:(C++,c++,qt,多态)