大家好,我对模板和多态性有一个疑问。按照定义,多态提供代码的可重用性,而模板在某种程度上允许用户使用相同的代码,通过提供不同的数据类型进行泛型编程。那么,使用多态性比使用模板有什么好处呢?这可能是一个愚蠢的问题,但我很想知道确切的区别。
大家好,我对模板和多态性有一个疑问。按照定义,多态提供代码的可重用性,而模板在某种程度上允许用户使用相同的代码,通过提供不同的数据类型进行泛型编程。那么,使用多态性比使用模板有什么好处呢?这可能是一个愚蠢的问题,但我很想知道确切的区别。
你好像误解了什么是多态。
多态的核心与派生类无关。多态只是指能够在不知道类型的情况下使用该类型的能力。多态不使用具体类型,而是依赖某种原型来定义它所接受的类型。符合该原型的任何类型都被接受。
C++ 中提供的运行时多态性是通过从包含虚函数的基类派生类来实现的。基类和虚函数构成了多态原型。编写为调用这些虚函数并接受基类的代码将接受从基类派生的 任何 类实例。
编译时 多态是发生在...编译时的多态;) 这意味着编译器必须知道正在发生的事情。你可能已经针对多态原型编写了 C++ 代码,但编译器并不关心。你将在编译后获得具体的特定类型。
C++中通过模板实现编译时多态。模板函数或类可以采用符合原型(通常称为“概念”)的任何类型。与基类和虚函数不同,原型是隐式的:原型仅由模板函数/类如何通过该类型使用来定义。
如果你有这个模板函数:
template<typename T>
void Stuff(T &t)
{
t.call(15);
}
对于 T
,存在一个隐含的要求。这个要求是它必须有一个名为 call
的成员函数,并且在调用时可以传入一个整数值。
这意味着任何符合这个原型的类型都可以被使用。
模板多态性比继承多态性更加广泛,因为它可以被更广泛的类型使用。一个类型必须专门设计为使用继承多态性;你必须从一个类派生。一个类型可以被非破坏性地(例如:无需改变类型本身)适应于模板多态性。如果你的模板原型设计得很好,那么更是如此:
template<typename T>
void Stuff(T &t)
{
call(t, 15);
}
Stuff
只需要有一些函数接受一个T&
和一个整数值。如果我想要使用Stuff
来处理某种类型,我只需要在适当的命名空间(即定义该类型的命名空间)中定义一个call
函数。这将完美地工作,而无需修改类型本身。int
不应该是模糊的,可能还有其他我忘记的条件。这就是为什么多态原型通常以“此表达式必须具有以下属性:…”的术语记录的原因。如果您尝试根据存在哪些函数和重载来记录它,则会涉及各种边缘情况。 - Steve JessopCategory<ObjectType, MorphismType>
与 Category(Objects, Morphisms)
为例。我认为,由于您可以将任何有限集合作为对象集合,因此我应该使用多态性来编写代码,并仅在它们可以减少编码负担的情况下使用模板。 - D Left Adjoint to UList<int>
和 List<float>
。AbstractInterface::openFile
接口及其派生类 WindowsInterface::openFile
和 LinuxInterface::openFile
。根据上下文使用其中之一。抽象接口确定了概念上执行相同操作的共性,派生类满足了实现概念变量性的需求。