所以我几乎了解它是如何工作的,但我无法理解它是什么使它有用.您仍然必须定义所有单独的函数,您仍然必须创建每个对象的实例,所以为什么不从该对象调用该函数与创建对象,创建指向父对象的指针并传递派生对象引用,只是为了调用一个函数?我不明白采取这一额外步骤的好处.
为什么这样:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
Parent* bar = &foo;
bar->function();
return -3234324;
}
Run Code Online (Sandbox Code Playgroud)
对此:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
foo.function();
return -3234324;
}
Run Code Online (Sandbox Code Playgroud)
他们做的完全一样吗?据我所知,只有一个人使用更多的记忆和更多的混乱.
Alo*_*ave 16
您的示例都以不同的方式执行相同的操作.
第一个示例function()使用静态绑定调用,而第二个示例使用动态绑定调用它.
在第一种情况下,编译器精确地知道在编译时自己调用哪个函数,而在第二种情况下,应该在运行时决定调用哪个函数,这取决于Base类指针指向的对象的类型.
有什么好处?
优点是更通用和松散耦合的代码.
想象一下类层次结构如下:

使用这些类的调用代码如下:
Shape *basep[] = { &line_obj, &tri_obj,
&rect_obj, &cir_obj};
for (i = 0; i < NO_PICTURES; i++)
basep[i] -> Draw ();
Run Code Online (Sandbox Code Playgroud)
其中,line_obj,tri_obj等是具体的形状类的对象Line,Triangle等等,并且它们被存储更一般化的基类的类型的指针的阵列中Shape.
这提供了额外的灵活性和松耦合,如果你需要添加另一个具体的形状类Rhombus,那么调用代码不需要改变很多,因为它引用了所有具有指向Base类的指针的具体形状Shape.您只需要使Base类指针指向新的具体类.
同时,调用代码可以调用这些类的适当方法,因为该Draw()方法在这些类中是虚拟的,并且调用的方法将在运行时决定,具体取决于基类指针指向的对象.
以上是应用着名的SOLID设计原则的开放闭合原理的一个很好的例子.
假设你想让某人出现在工作中.你不知道他们是需要开车,坐公共汽车,步行还是什么.你只是希望他们出现在工作中.有了多态性,你只需告诉他们出现工作,他们就是这样.如果没有多态性,您必须弄清楚他们需要如何工作并将他们引导到该流程.
现在说有些人开始使用赛格威工作.如果没有多态性,那些告诉某人上班的每一段代码都必须学习这种新的工作方式,以及如何找出以这种方式工作的人以及如何告诉他们这样做.使用多态性,你可以将代码放在一个地方,在Segway-rider的实现中,所有告诉人们去上班的代码告诉Segway-riders带他们的Segways,尽管它不知道这是什么它正在做.
有许多现实世界的编程类比.假设您需要告诉某人他们需要调查的问题.他们首选的联系机制可能是电子邮件,也可能是即时消息.也许这是一条短信.使用多态通知方法,您可以添加新的通知机制,而无需更改可能需要使用它的每一段代码.