首页 > 解决方案 > 为什么我们实际上需要运行时多态性?

问题描述

我试图理解多态性,但我不明白如果静态多态性可以很好地调用类的成员,为什么我们需要运行时多态性。

就像,假设这是一个问题。

#include <bits/stdc++.h>
using namespace std;
class base{
    public:
        virtual void fun(){
            cout<<"base called"<<endl;
        }
};
class derived:public base{
    public:
        void fun(){
            cout<<"derived called"<<endl;
        }
};
int main() {

    base b,*b1;
    derived d;
    b1 = &d;
    b1->fun();
    // b.fun();
    // d.fun();
}

假设这是我的代码,我想访问派生类或基类的函数,我可以通过简单地创建该类的对象来做到这一点,所以如果没有问题,那么为什么我们尝试使用引用调用对象(运行时多态性)。有人可以解释对运行时多态性的实际需求,或者如果可能的话,您可以通过使用任何现实生活场景来解释它吗?

标签: c++ooppolymorphism

解决方案


多态性被认为是面向对象编程的重要特征之一。C++中的多态主要分为两种:

  • 编译时多态性:这种类型的多态性是通过函数重载或运算符重载来实现的。

  • 运行时多态性:这种类型的多态性是通过函数覆盖实现的。

现在考虑以下场景。

假设我们有一个名为的基类Shape,它具有以下接口。

class Shape {
public:
    Shape(int init_x, int init_y);
    virtual ~Shape() = default;

    virtual void scale(int s) = 0;
protected:
    int x;
    int y;
};

现在我们要继承另外两个名为RectangleandCircle的类。

class Rectangle : public Shape {
public:
    Rectangle(int init_x, int init_y, int w, int h);
    void scale(int s) override;
private:
    int width;
    int height;
};
class Circle : public Shape {
public:
    Circle(int init_x, int init_y, int r);
    void scale(int s) override;
private:
    int radius;
};

您可能知道,圆形和矩形形状对它们的scale方法有不同的实现,所以我不能在Shape课堂上实现它。

现在假设我们有一个程序将所有形状存储在一个容器中vector<Shape*>(例如,它从用户那里获取所有形状一次并将它们存储在这个容器中)。

如果我们想scale在其中一个形状上使用方法,我们实际上并不知道我们正在处理哪种形状,但它会将我们的scale方法调用绑定到其适当的实现。


推荐阅读