C#中构造函数和析构函数的用法(三)
B b = new B(); //执行基类A的构造函数A() 再执行派生类的构造函数B()
B b = new B( ); //执行基类A的构造函数A() 再执行派生类的构造函数B(int)
B b = new B( ); //执行执行基类A的构造函数A(int) 再执行派生类的
构造函数B(int int)
在这里构造函数的执行次序是一定要分析清楚的 另外 如果基类A中没有提供无参构造函数public A( ) { x = ; } 则在派生类的所有构造函数成员初始化表中必须指出基类A的有参构造函数A(i) 如下所示
class A { private int x; public A( int i ) { x = i; } }; class B : A { private int y; public B():A(i) { y = ; } public B(int i):A(i) { y = i; } public B(int i int j):A(i) { y = j; } };
三.析构函数和垃圾回收器在C#中的运用
析构函数是实现销毁一个类的实例的方法成员 析构函数不能有参数 不能任何修饰符而且不能被调用 由于析构函数的目的与构造函数的相反 就加前缀 ~ 以示区别
虽然C#(更确切的说是CLR)提供了一种新的内存管理机制 自动内存管理机制(Automatic memory management) 资源的释放是可以通过 垃圾回收器 自动完成的 一般不需要用户干预 但在有些特殊情况下还是需要用到析构函数的 如在C#中非托管资源的释放
资源的释放一般是通过 垃圾回收器 自动完成的 但具体来说 仍有些需要注意的地方
值类型和引用类型的引用其实是不需要什么 垃圾回收器 来释放内存的 因为当它们出了作用域后会自动释放所占内存 因为它们都保存在栈(Stack)中;
只有引用类型的引用所指向的对象实例才保存在堆(Heap)中 而堆因为是一个自由存储空间 所以它并没有像 栈 那样有生存期( 栈 的元素弹出后就代表生存期结束 也就代表释放了内存) 并且要注意的是 垃圾回收器 只对这块区域起作用;
然而 有些情况下 当需要释放非托管资源时 就必须通过写代码的方式来解决 通常是使用析构函数释放非托管资源 将用户自己编写的释放非托管资源的代码段放在析构函数中即可 需要注意的是 如果一个类中没有使用到非托管资源 那么一定不要定义析构函数 这是因为对象执行了析构函数 那么 垃圾回收器 在释放托管资源之前要先调用析构函数 然后第二次才真正释放托管资源 这样一来 两次删除动作的花销比一次大多的 下面使用一段代码来示析构函数是如何使用的
public class ResourceHolder { … ~ResourceHolder() { // 这里是清理非托管资源的用户代码段 } }
四.小结
lishixinzhi/Article/program/net/201311/14870