它们之间有很大的区别。在C ++中,您不必为泛型类型指定类或接口。这就是为什么您可以创建真正的泛型函数和类,而不必担心松散的键入:template <typename T> T sum(T a, T b) { return a + b; }。
一、Java中的泛型与C中的泛型的区别
它们之间有很大的区别。在C ++中,您不必为泛型类型指定类或接口。这就是为什么您可以创建真正的泛型函数和类,而不必担心松散的键入。
1 | template <typename T> T sum(T a, T b) { return a + b; } |
上面的方法添加了两个相同类型的对象,并且可以用于任何具有” +”运算符的类型T。
在Java中,如果要在传递的对象上调用方法,则必须指定一种类型,例如:
1 | <T extends Something> T sum(T a, T b) { return a.add ( b ); } |
在C ++中,泛型函数/类只能在标头中定义,因为编译器会针对不同的类型(使用其调用)生成不同的函数。因此编译速度较慢。在Java中,编译不会带来很大的损失,但是Java使用一种称为”擦除”的技术,其中泛型在运行时被擦除,因此在运行时Java实际上正在调用…
1 | Something sum(Something a, Something b) { return a.add ( b ); } |
因此,Java中的通用编程并不是真正有用,它只是语法上的一点帮助新的foreach构造。
基本上,在C ++中,模板基本上是经过修饰的预处理器/宏集(注意:由于某些人似乎无法理解类推,因此我并不是说模板处理是宏)。在Java中,它们基本上是语法糖,可以最大程度地减少对象的样板转换。这是对C ++模板与Java泛型的相当不错的介绍。
要详细说明这一点:使用C ++模板时,基本上是在创建代码的另一个副本,就像使用#define宏一样。这使您可以执行诸如在模板定义中使用int参数来确定数组大小等操作。
延伸阅读:
二、C++泛型
C++泛型跟虚函数的运行时多态机制不同,泛型支持的静态多态,当类型信息可得的时候,利用编译期多态能够获得最大的效率和灵活性。当具体的类型信息不可得,就必须诉诸运行期多态了,即虚函数支持的动态多态。
对于C++泛型,每个实际类型都已被指明的泛型都会有独立的编码产生,也就是说list和list生成的是不同的代码,编译程序会在此时确保类型安全性。由于知道对象确切的类型,所以编译器进行代码生成的时候就不用运用RTTI,这使得泛型效率跟手动编码一样高。
显然这样的做法增加了代码空间,相比运行时多态,是以空间换时间。