Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the difference in generic programming between Java and C++

2025-02-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

这篇文章主要讲解了"Java和C++的泛型程序设计有什么不同",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java和C++的泛型程序设计有什么不同"吧!

泛型程序设计:

1. 泛型类的定义,见如下代码:

public class Pair { public Pair() { first = null; second = null; } public Pair(T first,U second) { this.first = first; this.second = second; } public T getFirst() { return first; } public U getSecond() { return second; } public void setFirst(T first) { this.first = first; } public void setSecond(U second) { this.second = second; } private T first; private U second; }

以上代码中的T,U都是泛型类Pair的类型参数。以下为C++中模板类的定义方式:

template class Pair { public: Pair(T first,U second): _first(first),_second(second) {} ~Pair() {} public: T getFirst() { return _first; } U getSecond() { return _second; } void setFirst(T frist) { _first = first; } void setSecond(U second) { _second = second; } private: T _first; U _second; }

2. 泛型方法的定义,在Java中泛型方法不一定声明在泛型类中,可以声明在普通类中,见如下代码:

public class MyFirst { public static void main(String[] args) throws Exception { String[] names = {"john","Q.","Public"}; String middle = ArrayAlgo.getMiddle(names); System.out.println(middle); } } class ArrayAlgo { public static T getMiddle(T[] a) { return a[a.length/2]; } }

在以上代码中可以看出getMiddle方法为静态泛型方法,类型变量位于修饰符"public static" 的后面,返回值的前面。调用的时候在方法名的前面给出了参数类型。由于Java的编译器提供类型推演的功能,既类型参数可以通过函数参数的类型进行推演,因此也可以直接调用泛型函数,如String middle = ArrayAlgo.getMiddle(names)。如果编译器无法通过函数参数的类型推演出类型参数的实际类型,这样将会导致编译错误。在C++中同样存在模板函数,也同样存在模板函数的类型推演,在这一点上主要的差异来自于函数声明的语法,见如下C++代码:

class ArrayAlgo { public: template static T getMiddle(T* a,size_t len) { return a[len/2]; } }; int main() { int v[] = {1,2,3}; int ret = ArrayAlgo::getMiddle(v,3); printf("This value is %d.\n",ret); return 0; }

3. 类型参数的限定:有些泛型函数在使用类型参数变量时,经常会用到该类型的特殊方法,如在进行数组元素比较时,要求数组中的元素必须是Comparable接口的实现类,见如下代码:

public static T min(T[] a) { if (a == null || a.length == 0) return null; T smallest = a[0]; for (int i = 0; i

< a.length; ++i) { if (smallest.compareTo(a[i]) >

0) smallest = a[i]; } return smallest; }

In the above code, the array element is of type T. If the type does not provide a compareTo field method, it will cause a compilation error. How to ensure that the type parameter does provide a compareTo method? If T is an implementation class of the Comparable interface, then the method must be provided, so this can be ensured by the type parameter qualification provided in Java syntax. See revision codes below:

public static T min(T[] a) { if (a == null || a.length == 0) return null; T smallest = a[0]; for (int i = 0; i

< a.length; ++i) { if (smallest.compareTo(a[i]) >

0) smallest = a[i]; } return smallest; }

The syntax guarantees that the type argument must be an implementation class of the Comparable interface, otherwise it will cause a compilation error. Java can support multiple interface qualifications, separated by &, as in the previous example, although it will also lead to compilation errors, but the latter will not only produce more explicit compilation error messages, but also make it clearer for users to see the rules of use of the method. There is no such qualification in standard C++, but there is another name for this in C++, called "type binding," which is imitated in open source libraries such as Boost by more sophisticated templating techniques. However, C#support is pretty good for this feature of generics, see which keyword in C#generics.

In standard C++, the template implementation is more flexible and powerful than Java. For the code in *** examples, only the compareTo method must be provided for the module parameter to compile.

template static T min(T* a,size_t len) { T smallest = a[0]; for (int i = 0; i

< len; ++i) { if (smallest.compareTo(a[i]) >

0) smallest = a[i]; } return smallest; }

注:C++中的模板是在引用时才编译的,因此如果在模板类型中出现任何语法错误,但此时尚未有任何引用时,编译器是不会报错的。

4. 泛型代码中的类型擦除:记得在我阅读Thinking in Java 4th 的时候,书中给出了一些比较明确的解释,为什么Java会这样实现泛型,其最主要的原因是为了考虑向前兼容,也承认这样的实现方式有着很多的缺陷和弊病,希望Java在今后的版本中予以补足。

简单的说类型擦除,就是几乎所有的泛型相关的行为都是由编译器通过暗插各种各样的代码,或者是暗自修订部分代码的声明,然后再将修订后的代码(基本不再包含泛型信息)生成字节码后交给JVM去执行,因此可以据此判断在JVM中对我们的泛型类型是一无所知的。C++也是同样的道理,只是编译器完成的工作被定义为类型展开或类型实例化,因此,同样的模板类,如果实例化的类型参数不同,那么用他们声明出来的类对象也同样不属于相同类型的对象,其限制主要表现为,不能通过缺省copy constructor或者缺省赋值操作符来完成对象之间的复制,除非其中某个类型实例化后的对象专门针对另外一种类型实例化后的类型进行了copy constructor和赋值等于的重载。

1) 类型擦除:将类型参数替换为限定类型,如果没有限定类型则替换为Object,见如下代码:

public class Pair { public Pair(T first,T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } public void setFirst(T first) { this.first = first; } public void setSecond(T second) { this.second = second; } private T first; private T second; }

由于Pair中的类型参数T没有限定类型,因此类型擦除后将会变成如下代码:

public class Pair { public Pair(Object first,Object second) { this.first = first; this.second = second; } public Object getFirst() { return first; } public Object getSecond() { return second; } public void setFirst(Object first) { this.first = first; } public void setSecond(Object second) { this.second = second; } private Object first; private Object second; }

因此尽管在调用Pair时,传递的类型参数有所不同,如String、Date,但是在类型擦除之后,他们将成为相同的类型。如果类型参数存在多个限定类型,则取***个限定类型作为擦除后的类型参数,见如下代码:

public class Interval implements Serializable { public Interval(T first, T second) { if (first.compareTo(second)

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report