模板和多态性有什么区别 [英] what is the difference between templates and polymorphism

查看:413
本文介绍了模板和多态性有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我对模板和多态性有疑问.通过定义,多态性提供了代码可重用性,并且模板在某种意义上允许用户通过提供具有不同数据类型的通用编程来使用相同的代码.那么,使用多态性而不是模板有什么好处.这可能是一个愚蠢的问题,但我很好奇知道确切的区别.

Hi all I have a doubt regarding templates and polymorphism. By definition polymorphism provides code reusability, and templates in some sense allows the user to use the same code by providing generic programming with different data types. So what is the benefit of using polymorphism over templates. It might be a silly questions but I am curious to know the exact difference.

推荐答案

您似乎误解了什么是多态性.

You seem to misunderstand what polymorphism is.

多态性的核心与派生类无关.多态只不过是指在不了解类型的情况下使用类型的能力.多态性不是使用具体的类型,而是依靠某种形式的原型来定义所采用的类型.任何适合该原型的类型都会被接受.

Polymorphism, at its core, has nothing to do with derived classes. Polymorphism simply means the ability to use a type without knowing everything about it. Rather than using a concrete type, polymorphism relies on some form of prototype to define what types it takes. Any types that fit that prototype are accepted.

在C ++中,运行时多态是通过从包含虚拟函数的基类派生类来提供的.基类和虚函数构成了多态原型.为接受调用这些虚拟函数的基类而编写的代码将接受从基类派生的 any 类实例.

Runtime polymorphism, in C++, is provided by deriving classes from a base class that contains virtual functions. The base class and virtual functions form the polymorphic prototype. Code written to accept the base class that calls these virtual functions will accept any class instance derived from the base class.

编译时多态性是在编译时发生的多态性;)这意味着编译器必须知道正在发生的事情.您可能已经针对多态原型编写了C ++代码,但是编译器不在乎.编译后会得到特定的具体类型.

Compile-time polymorphism is polymorphism that happens... at compile time ;) What this means is that the compiler must know what is going on. You may have written the C++ code against a polymorphic prototype, but the compiler doesn't care. You get specific concrete types post-compilation.

编译时多态性由C ++中的模板提供.模板函数或类可以采用符合原型的任何类型,通常称为概念".与基类和虚函数不同,原型是隐式:仅通过模板函数/类使用的类型来定义原型.

Compile-time polymorphism is provided by templates in C++. A template function or class can take any type which conforms to a prototype, usually called a "concept". Unlike base classes and virtual functions, the prototype is implicit: the prototype is defined only by how the type is used by the template function/class.

如果您具有此模板功能:

If you have this template function:

template<typename T>
void Stuff(T &t)
{
  t.call(15);
}

T上有一个隐式要求.此要求是它具有一个称为call的成员函数.此成员函数必须有一个重载,可以使用整数值对其进行调用.

There is an implicit requirement on T. This requirement is that it has a member function called call. There must be a single overload of this member function which can be called with an integer value.

这意味着可以使用恰好适合此原型的任何类型.

This means that any type that happens to fit this prototype can be used.

模板多态性比继承多态性更广泛,因为它可以被更广泛的类型使用.必须专门设计一种类型以使用继承多态性.你必须从一个类中派生出来.类型可以是非破坏性的(即:您不必更改类型本身),以适应模板多态性.更重要的是,如果您的模板原型设计合理:

Template polymorphism is more broad than inheritance polymorphism, because it can be used by a broader array of types. A type has to be designed specifically to use inheritance polymorphism; you have to derive from a class. A type can be non-destructively (ie: you don't have to change the type itself) adapted to template polymorphism. Even moreso if your template prototype is well designed:

template<typename T>
void Stuff(T &t)
{
  call(t, 15);
}

此版本的Stuff所需要的全部就是,有些函数需要一个T&和一个整数值.如果我想与Stuff一起使用某种类型,我要做的就是在适当的名称空间(即定义该类型的名称空间)中定义一个call函数.这样就可以了.都没有修改类型本身.

All that this version of Stuff requires is that there is some function that takes a T& and an integer value. If I have some type that I want to use with Stuff, all I have to do is define a call function in an appropriate namespace (namely, the namespace that the type was defined in). And this will work just fine. All without modifying the type itself.

当然,编译时多态是...编译时.如果我希望某些用户输入或数据文件选择多态类型,则模板并不能提供很多帮助(尽管基于模板的技术类型擦除可以提供帮助).运行时多态性的主要好处是它确实是运行时.

Of course, compile-time polymorphism is... compile-time. If I want some user input or data file to select the polymorphic type, templates aren't going to help a whole lot (though type erasure, a template-based technique, can help). The principle benefit of runtime polymorphism is that it is indeed runtime.

另一个好处是它的原型更加精确.关于继承的所有内容均已明确声明.基类中的虚函数接口已明确布置.编译器将阻止您尝试不正确地使用该基类(调用其上不存在的方法).确实,一个不错的IDE会指导您的代码,以便您只会在基类上看到这些方法.

Another benefit is that it is more precise about its prototypes. Everything is explicitly stated about inheritance. The virtual function interface in a base class is clearly laid out. The compiler will stop you from attempting to use that base class incorrectly (calling methods that don't exist on it). Indeed, a decent IDE will guide your code so that you will only see the methods on the base class.

模板多态性更加隐含.由于C ++无法拼写出特定模板函数/类放在类型上的原型,因此很容易意外地在模板类型上调用了您不应该调用的东西.仅当您尝试使用不适合原型的类型时,编译器才会检测到此错误.即使这样,通常也会产生大量错误(取决于模板代码的嵌套深度),这使得很难知道问题出在哪里.

Template polymorphism is a lot more implicit. Since C++ has no way of spelling out the prototype that a particular template function/class puts on a type, it's very easy to accidentally call something on a template type that you shouldn't. The compiler will only detect this when you try to use a type that doesn't fit the prototype. And even then you will generally get a massive error spew (depending on how deeply nested your template code is) that makes it difficult to know where the problem is.

实现隐式模板多态原型也要困难得多,因为它没有被阐明.实现派生类需要遍历基类,查看所有虚函数并实现它们.对于模板原型,这样做要困难得多,除非在某个地方有说明它的文档.如果您未能实现某些目标,那么您将再次得到错误喷出的信息,通常该错误要比即将发生的问题少.

It's also a lot harder to implement the implicit template polymorphic prototype, since it isn't spelled out. Implementing a derived class requires walking through the base class, looking at all of the virtual functions, and implementing them. Doing this for a template prototype is much more difficult, unless there is documentation somewhere that spells it out. If you fail to implement something, you again get an error spew that is generally less than forthcoming about the problem.

这篇关于模板和多态性有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆