template <typename T> T sum(T a, T b) { return a + b; }
template <typename T> T sum(T* a, T* b) { return (*a) + (*b); }
Special sum(const Special& a, const Special& b) { return a.plus(b); }
public class PhoneNumbers {
private Map phoneNumbers = new HashMap();
public String getPhoneNumber(String name) {
return (String) phoneNumbers.get(name);
}
}
我也可以推荐 用 Java 思考。作为一个 C + + 程序员,很多像对象这样的概念已经是第二天性了,但是还是有一些细微的差别,所以即使你略读了一些部分,有一个介绍性的文本也是值得的。
在学习 Java 时,您将学到的很多东西是所有的库(包括标准的(JDK 中提供的)和非标准的(包括 Spring 等常用的))。Java 语法比 C + + 语法更加冗长,没有很多 C + + 的特性(比如运算符重载、多重继承、析构函数机制等等) ,但是严格来说这也不能使它成为 C + + 的一个子集。
import java.io.*;
interface ScalarProduct<A> {
public Integer scalarProduct(A second);
}
class Nil implements ScalarProduct<Nil>{
Nil(){}
public Integer scalarProduct(Nil second) {
return 0;
}
}
class Cons<A implements ScalarProduct<A>> implements ScalarProduct<Cons<A>>{
public Integer value;
public A tail;
Cons(Integer _value, A _tail) {
value = _value;
tail = _tail;
}
public Integer scalarProduct(Cons<A> second){
return value * second.value + tail.scalarProduct(second.tail);
}
}
class _Test{
public static Integer main(Integer n){
return _main(n, 0, new Nil(), new Nil());
}
public static <A implements ScalarProduct<A>>
Integer _main(Integer n, Integer i, A first, A second){
if (n == 0) {
return first.scalarProduct(second);
} else {
return _main(n-1, i+1,
new Cons<A>(2*i+1,first), new Cons<A>(i*i, second));
//the following line won't compile, it produces an error:
//return _main(n-1, i+1, first, new Cons<A>(i*i, second));
}
}
}
public class Test{
public static void main(String [] args){
System.out.print("Enter a number: ");
try {
BufferedReader is =
new BufferedReader(new InputStreamReader(System.in));
String line = is.readLine();
Integer val = Integer.parseInt(line);
System.out.println(_Test.main(val));
} catch (NumberFormatException ex) {
System.err.println("Not a valid number");
} catch (IOException e) {
System.err.println("Unexpected IO ERROR");
}
}
}
在 C # 中,你可以写几乎相同的东西。尝试用 C + + 重写它,它不会编译,抱怨模板的无限扩展。
这与 C + + 有很大的不同。在 C + + 中,模板本质上是一个经过美化的宏集,编译器为每种类型创建一个新的模板代码副本。证明这一点的事实是,MyClass 的实例将不与 MyClass 共享静态变量。然而,MyClass 的两个实例将共享一个静态变量。
/*** MyClass.h ***/
template<class T> class MyClass {
public:
static int val;
MyClass(int v) { val v;}
};
/*** MyClass.cpp ***/
template<typename T>
int MyClass<T>::bar;
template class MyClass<Foo>;
template class MyClass<Bar>;
/*** main.cpp ***/
MyClass<Foo> * fool
MyClass<Foo> * foo2
MyClass<Bar> * barl
MyClass<Bar> * bar2
new MyClass<Foo>(10);
new MyClass<Foo>(15);
new MyClass<Bar>(20);
new MyClass<Bar>(35);
int fl fool->val; // will equal 15
int f2 foo2->val; // will equal 15
int bl barl->val; // will equal 35
int b2 bar2->val; // will equal 35
在 Java 中,静态变量在 MyClass 的各个实例之间共享,与不同的类型参数无关。
Java 泛型和 C + + 模板还有其他一些不同之处,包括:
C + + 模板可以使用原语类型,比如 int
而是使用 Integer。
在 Java 中,可以将模板的类型参数限制为
例如,您可以使用泛型来实现
并指定 type 参数必须从
纸牌游戏。
在 C + + 中,类型参数可以实例化,而 Java 不能
支持这个。
在 Java 中,type 参数(即 MyClass 中的 Foo)不能是
用于静态方法和变量,因为这些方法和变量将在 MyClass 和 MyClass 之间共享。在 C + + 中,这些类是不同的,所以 type 参数可以用于静态方法和变量。
在 Java 中,MyClass 的所有实例,不管它们的类型参数是什么,都是相同的类型。类型参数在运行时被擦除。在 C + + 中,具有不同类型参数的实例是不同类型的。