为什么我们实际上需要运行时多态性?

时间:2020-05-31 07:47:12

标签: c++ oop polymorphism

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

就像,假设这是个问题。

#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();
}

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

3 个答案:

答案 0 :(得分:2)

在无法在编译时准确告知软件运行时一切情况的时候,或者当您需要一个容器来容纳所有实现通用功能的异构对象时,多态性很有用界面。

一个很好的例子是UI工具箱。几乎所有的UI工具包都具有可以容纳其他小部件的容器的概念,但是UI工具包的作者不知道要将什么小部件放入容器中。由于容器需要能够处理任何类型的小部件,因此多态是实现此目的的最简单方法。

答案 1 :(得分:1)

假设您有一个包含一个类的库,并且带有几个指向该类的指针的方法。

class GameObject {

public:
    virtual void print_to_display(void);

};

class Game {

public:
    void add_obj(GameObject *obj);
};

从那时起,您只有库(共享库和少量头文件),并且您不想修改库的源代码(因为它可能会破坏现有方法)。

您可以在项目中扩展类GameObject,并且overrideprint方法的一种,它可以执行默认行为以外的其他操作。

class MyObject: public GameObject {

public:
    void paint(void) override;
};

答案 2 :(得分:1)

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

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

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

现在考虑以下情形。

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

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; }; Rectangle的类。

Circle
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方法调用绑定到适当的形状实施。

相关问题