使用通用方法的优点和缺点是什么(在编译时,运行时,性能和内存方面)?
最佳答案
好的,Java泛型和C++模板是如此不同,以至于我不确定是否可以在一个问题中回答它们。
Java Generics
这些几乎是语法糖。它们通过一个有争议的决定type erasure来实现。他们真正要做的只是防止您大量转换,这使它们使用起来更安全。除了使用原始数据类型(int,float,double,char,bool,short)的情况外,性能与制作专用类相同。在这些情况下,值类型必须装箱成其对应的引用类型(整数,浮点数, double 型,字符, boolean 型,短型),这会产生一些开销。内存使用情况是相同的,因为JRE只是在后台执行转换(基本上是免费的)。
Java也有一些不错的类型covariance and contravariance,这使事情看上去比不使用它们干净得多。
C++模板
这些实际上根据输入类型生成不同的类。 std::vector<int>
是与std::vector<float>
完全不同的类。不支持协方差或相反,但支持将非类型传递给模板,即部分模板专门化。他们基本上可以让您做任何您想做的事情。
但是,由于C++模板会为其模板参数的每个变体创建不同的类,因此编译后的可执行文件的大小会更大。除此之外,编译时间大大增加,因为所有模板代码都必须包含在每个编译单元中,并且必须生成更多的代码。但是,实际的运行时内存占用空间通常比备用内存要小(释放额外的void *),并且性能更好,因为编译器可以使用已知类型执行更积极的优化。
编辑(感谢DavidRodríguez):虽然泛型Java类完全是自己编译的,但是在使用C++模板时,您只能编译所用的东西。因此,如果创建std::vector<int>
并仅使用push_back
和size
,则只有那些函数会被编译到目标文件中。这减轻了可执行文件问题的规模。
如果您对它们之间的差异感到好奇,请查看C#,Java和C++中泛型的this comparison。