我注意到某处多态只是指虚函数。但是,在某些地方它们包括函数重载和模板。后来,我发现有两个术语,编译时多态和运行时多态。真的吗?
我的问题是,当我们一般性地讨论多态性时,广泛接受的含义是什么?
答案 0 :(得分:13)
是的,你是对的,在C ++中有两种公认的多态性“类型”。他们的意思几乎就是你认为的意思
是C#/ Java / OOP人通常简称为“多态”的东西。它本质上是子类化,要么从基类派生并覆盖一个或多个虚函数,要么实现接口。 (在C ++中通过覆盖属于抽象基类的虚函数来完成)
在编译时发生,可以被认为是变形的变形。这里的想法很简单,尽管完全不相关,但在函数中可以使用不同的类型来表示相同的概念。有一个非常简单的例子,请考虑这个
template <typename T>
T add(const T& lhs, const T& rhs) { return lhs + rhs; }
如果这是动态多态,那么我们将定义add
函数以将某种“IAddable”对象作为其参数。尽管实现了不同的实现,但是可以使用实现该接口(或从该基类派生)的任何对象,这为我们提供了多态行为。我们不关心哪种类型传递给我们,只要它实现某种“可以加在一起”的界面。
但是,编译器实际上知道传递给函数的类型。确切类型仅在运行时已知,因此这是动态多态。
但是,我们不要求您从任何内容派生,类型T
只需要定义+
运算符。然后插入静态。所以在编译时,我们可以在任何有效类型之间切换,只要它们行为相同(意味着它们定义了我们需要的成员)
这是另一种形式的多态性。原则上,效果是相同的:该函数适用于我们感兴趣的概念的任何实现。我们不关心我们处理的对象是字符串,int,浮点数还是复数,只要它实现了“可以加在一起”概念。
由于使用的类型是静态已知的(在编译时),因此称为静态多态。实现静态多态的方式是通过模板和函数重载。
但是,当C ++程序员只是说多态时,他们通常会引用动态/运行时多态。
(请注意,对于所有语言来说并不一定如此。函数式程序员在使用术语时通常意味着静态多态性 - 使用某种参数化类型定义泛型函数的能力,类似于模板)
答案 1 :(得分:8)
“多态”字面意思是“多种形式”。不幸的是,这个术语在计算机科学中有点超载(原谅双关语)。
根据FOLDOC,多态性是“由Christopher Strachey(1967)首先确定并由Hindley和Milner开发的概念,允许诸如任何列表之类的类型。”
通常,它是“一种允许使用统一接口处理不同数据类型的值的编程语言特性”,引用Wikipedia,这继续描述两种主要类型的多态:
参数多态性是指相同代码可以应用于多种数据类型的情况。面向对象编程社区中的大多数人将此称为“泛型编程”而不是多态。泛型(以及某种程度上的模板)适合此类别。
Ad-hoc 多态性是不同代码用于不同数据类型的时候。重载属于此类别,覆盖也是如此。这就是面向对象社区中的人们在说“多态”时通常所指的。 (事实上,当他们使用术语“多态性”时,许多意味着重写,而不是超载)
对于ad-hoc多态性,还存在实现代码的解析是在运行时(动态)还是在编译时(静态)发生的问题。方法重载通常是静态的,方法重写是动态的。这是术语静态/编译时多态性和动态/运行时多态性的来源。
答案 2 :(得分:5)
通常人们根据我的经验提到运行时多态性......
答案 3 :(得分:5)
当C ++程序员说“多态”时,他很可能意味着子类型多态,这意味着“后期绑定”或“动态绑定”与虚函数。函数重载和泛型编程都是多态的实例,它们在编译时确实涉及静态绑定,因此它们可以统称为编译时多态。子类型多态性几乎总是被称为多态性,但该术语也可以指上述所有内容。
答案 4 :(得分:3)
以其最简洁的形式,多态性意味着一种类型看起来像是另一种类型的能力。
有两种主要类型的多态性。
D
来自B
,那么D
就是B
。C
实现接口I
。第一个是您正在考虑的运行时多态性。第二个并不真正适用于C ++,它实际上是一个适用于Java和C#的概念。
有些人确实认为运算符(+
,-
,/
,*
)的特殊情况下的重载是一种多态,因为它允许您可以考虑将这些运算符重载为彼此可替换的类型(即+
string
和+
int
)。这种多态概念最常用于动态语言。我认为这是滥用术语。
至于模板编程,你会看到一些使用术语“多态”,但这与我们通常所说的多态性实际上是非常不同的。这个概念的更好的名称是“通用编程”或“通用性”。
答案 5 :(得分:1)
各种类型的函数重载(编译时多态... 2011年6月9日...多态性意味着同一实体在不同时间表现不同。编译时多态也称为静态绑定。 http://churmura.com/technology/programming/various-types-of-function-overloading-compile-time-polymorphism-static-binding/39886/
答案 6 :(得分:1)
关于编译时多态性和运行时多态性的简单解释: questionscompiled.com
编译时间多态性:
C ++支持多态。一个功能多用途,或简称许多具有相同名称但具有不同功能体的功能。 对于每个函数,调用编译器在编译时将调用绑定到一个函数定义。这个几个函数之间的绑定决定是通过考虑函数的形式参数,它们的数据类型和它们的顺序来做出的。
运行时多态:
C ++允许绑定延迟到运行时。当你有一个具有相同名称的函数,相同数量的参数和基本类中相同序列的相同数据类型以及派生类和形式的函数调用:base_class_type_ptr-&gt; member_function(args);将始终调用基类成员函数。基类中成员函数上的关键字virtual指示编译器将绑定延迟到运行时。
每个具有至少一个虚函数的类都有一个vtable,可以帮助在运行时进行绑定。查看基类类型指针的内容,它将正确调用一个可能的派生/基类成员函数的成员函数。
答案 7 :(得分:0)
是的,你基本上是对的。编译时多态是模板的使用(其类型的实例各不相同,但在编译时是固定的)而运行时多态是指继承和虚函数的使用(其类型的实例在运行时变化并固定)