Java和C++在细节上的差异(一) (四)

2014-11-24 03:03:11 · 作者: · 浏览: 13
loyee a = new Employee("Alice",70000);
11 Employee b = new Employee("Bob",60000);
12 System.out.println("Before: a = " + a.getName());
13 System.out.println("Before: b = " + b.getName());
14 swap(a,b);
15 System.out.println("After: a = " + a.getName());
16 System.out.println("After: b = " + b.getName());
17 }
18 /* 结果如下:
19 Test swap
20 Before: a = Alice
21 Before: b = Bob
22 End of method: x = Bob
23 End of method: y = Alice
24 After: a = Alice
25 After: b = Bob */
  C++有值调用和引用调用,引用参数标有&符号。如:void tripleva lue(double& x)或void swap(Employee& x,Employee& y)方法实现修改他们引用参数的目的,既该方法执行完成后,调用函数的参数变量的值将发生改变。
  5. 对象的构造和构造函数:
  在Java中如果一个class没有定义任何构造函数,Java编译器将自动生成一个缺省的构造函数,没有任何参数,其行为只是按照Java默认的方式初始化该类的所有域变量,如数值型为0,布尔为false,对象则为null。但是如果该class定义了自己的构造函数,那么缺省构造函数将不会被自动生成,再试图调用自动生成的缺省构造函数将会导致编译错误。该行为和C++完全一致。但是Java提供了另外一种域变量初始化方式,如下:
1 public class Employee {
2 ...
3 private String name = ""; //直接赋值
4 private int id = assignId();//通过调用域方法完成初始化。
5 }
  在C++中不能直接在类的定义中以任何形式直接初始化成员变量。但是C++提供了在构造函数中以初始化列表的方式完成成员变量对象的初始化,特别是const成员,必须在这里赋值。
  通过一个构造器调用另一个构造器从而完成域变量的初始化和部分代码复用。通过this关键字(或称隐式参数)作为函数名,然后传入参数调用你期望的另一个构造函数,注:this被调用之前不能执行任何其他的code。
1 public Employee(double s) {
2 //calls Employee(String,double)
3 this("Employee #" + nextId,s);
4 ++nextId;
5 }
  在C++中如果打算完成此功能,必须将构造函数的部分逻辑抽取出来,以便让多个构造函数去调用,然后不同的构造函数之间不能直接调用。
  在Java定义的子类中,如果子类的构造函数不是调用父类的缺省构造函数,则需要在子类构造函数的第一行代码中指定欲调用的父类构造函数,该调用需要通过super关键字来完成。见如下代码:
1 public class MyFirst {
2 public static void main(String[] args) {
3 BaseClass bc1 = new SonClass();
4 BaseClass bc2 = new SonClass(5);
5 }
6 }
7
8 class BaseClass {
9 public BaseClass() {
10 System.out.println("This is BaseClass");
11 }
12
13 public BaseClass(int i) {
14 System.out.println("This is BaseClass with i.");
15 }
16 }
17
18 class SonClass extends BaseClass {
19 public SonClass() {
20 System.out.println("This is SonClass");
21 }
22
23 public SonClass(int i) {
24 super(5);
25 System.out.println("This is SonClass with i");
26 }
27 }
28 /* 结果如下:
29 This is BaseClass
30 This is SonClass
31 This is BaseClass with i.
32 This is SonClass with i */
  在C++中也可以完成该种类型的指定,但是必须在子类构造函数的初始化列表中完成对父类指定构造函数的调用。
1 class BaseClass {
2 public:
3 BaseClass() {
4 printf("This is BaseClass\n");
5 }
6
7 BaseClass(int i) {
8 printf("This is BaseClass with i\n");
9 }
10 };
11
12 class SonClass : public BaseClass {
13 public:
14 SonClass() {
15 printf("This is SonClass\n");
16 }
17
18 SonClass(int i) : BaseClass(i) {
19 printf("This is SonClass with i\n");
20 }
21 };
22
23 int main()
24 {
25 BaseClass* bc1 = new SonClass;
26 BaseClass* bc2 = new SonClass(5);
27 delete bc1;
28 delete bc2;
29 return 0;
30 }
31 /* 结果如下:
32 This is BaseClass
33 This is SonClass
34 This is