我试图理解多态性,但是我不明白为什么如果静态多态性可以很好地调用类的成员,为什么我们需要运行时多态性。
就像,假设这是个问题。
#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();
}
假设这是我的代码,并且我想访问派生类或基类的功能,并且能够通过简单地创建该类的对象来做到这一点,因此,如果没有问题,那么为什么我们尝试使用引用(运行时多态)。 有人可以解释对运行时多态性的实际需求吗,或者可以通过使用任何现实生活场景来解释吗?
答案 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
,并且override是print
方法的一种,它可以执行默认行为以外的其他操作。
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
方法调用绑定到适当的形状实施。