@夜猫子

导航

 
如题:
   1:      class A
   2:      {
   3:          public int num;
   4:          public A() { Console.WriteLine(".ctor() of A"); }
   5:          public A(int num)
   6:          {
   7:              Console.WriteLine(".ctor(int) of A");
   8:              this.num = num;
   9:          }
  10:          ~A() { Console.WriteLine("Finalize of A"); }
  11:      }
  12:      class B : A
  13:      {
  14:          public B(int num) { Console.WriteLine(".ctor(int) of B"); }
  15:          ~B() { Console.WriteLine("Finalize of B"); }
  16:      }
  17:   
  18:          static void Main(string[] args)
  19:          {
  20:              B b = new B(10);
  21:              Console.WriteLine(b.num);
  22:              b = null;
  23:              GC.Collect();
  24:              GC.WaitForPendingFinalizers();
  25:              Console.ReadLine();
  26:           }

输出结果?

.ctor() of A

.ctor(int) of B

0

Finalize of B

Finalize of A

 

上面这个题目考查的是构造函数和析构函数执行顺序的问题。

构造函数的执行顺序是:父类->子类,即先执行父类的构造函数,再执行子类的构造函数。多层继承总是从最上层的父类开始。

析构函数的执行顺序是:子类->父类,即先执行子类的析构函数,在执行父类的析构函数。

根据这个原则来解答这个题目:

1、子类B继承了父类A,所以在实例化B时,先执行父类A的构造函数。

父类A有两个构造函数,应该执行哪一个呢?

  如果子类B的构造函数继承时没有指定继承父类A的构造函数,默认执行父类A的默认构造函数。

  所以输出为:

   .ctor() of A

   .ctor(int) of B

  不会执行父类A带参的构造函数,那什么情况下会执行父类A带参的构造函数呢?只要把子类B的构造函数修改一下就可以了。

   1:  public B(int num):base(num) { Console.WriteLine(".ctor(int) of B"); }

  改成这样后输出结果为:

  .ctor(int) of A

  .ctor(int) of B

2、子类B继承了父类A的变量num,所以子类B可以使用变量num。但是子类B实例化时默认执行的是父类A的默认构造函数,所以变量num没有赋值,所以Console.WriteLine(b.num);这段代码输出结果为:0

3、析构函数的执行比较简单,按照“子类->父类”原则,输出结果为:

   Finalize of B

   Finalize of A

GC是.net的垃圾收集器,自动进行内存资源的回收,一般不需要程序员关心资源回收的问题。当一个对象没有任何引用的时候就可以被回收。一个对象可以被回收并不意味着一定会被立即回收,GC会选择时机进行回收。但是可以调用GC.Collect();来立即回收。对于垃圾回收机制以后再学习。

posted on 2012-12-06 10:42  @夜猫子  阅读(904)  评论(0)    收藏  举报