深入理解C#构造函数与析构函数

前言:在前面的博文中,我介绍了C#中的构造函数,详情戳:C#中的构造函数详解,建议收藏!在本博文接下来的部分,我将对构造函数、析构函数做一系列的补充,可谓是干货满满!话不多说,开始学习吧!

一、构造函数

首先,我们要明确C#中构造函数是什么,它能做什么,它的特点又是什么?为此,我专门的写了一篇博文介绍C#中的构造函数。那么接下来的内容,算是对其的一个补充,并给大家介绍一个与它紧密相关的——析构函数。

1、构造函数的概念

构造函数是一个特殊的函数,它是在创建对象时执行的方法,构造函数具有与类相同的名称,它通常用来初始化对象的数据成员。构造函数的特点如下:

  1. 构造函数没有返回值。
  2. 构造函数的名称要与本类的名称相同。

2、构造函数的定义

/// <summary>
/// 创建一个人类
/// </summary>
class Person
{
    public Person() // 无参数的构造函数
    {
        Console.WriteLine("我是Person无参的构造函数");
    }

    public Person(string name) // 有参数的构造函数
    {
        Console.WriteLine("我是Person有参的构造函数,你可以叫我{0}", name);
    }
}
  • public:构造函数的修饰符。
  • Person:构造函数的名称。
  • name:构造函数的参数。

3、默认构造函数与有参构造函数

在定义一个类时,如果没有定义构造函数,编译器则会自动创建一个不带参数的默认构造函数。例如我创建一个Animal类,如下:

/// <summary>
/// 创建一个动物类
/// </summary>
class Animal
{
    
}

在创建Anima类时,我们可使用如下代码:

Animal animal = new Animal();

如果我们在定义类时,定义了含有参数的构造函数,这时如果还想使用默认构造函数,就必须显式的进行定义,不然就会出错。例如下面这个案例:

class Animal
{
    public Animal(string name)
    {
        Console.WriteLine("我是Animal有参的构造函数,你可以叫我{0}", name);
    }
}
public static void Main(string[] args)
{
   Animal animal = new Animal();

}

在这里插入图片描述
上面这个错误主要是由于程序中已经定义了一个有参的构造函数,这时创建对象,如果想要使用无参构造函数,就必须进行显式定义。

4、静态构造函数

在C#中,可以为类定义静态构造函数,这种构造函数只执行一次。编写静态构造函数的主要原因是:类有一些静态字段或者属性,需要在第一次使用类之前,从外部源中初始化这些静态字段和属性。

定义静态构造函数时,不能设置访问修饰符,因为其他C#代码从来不会调用它,它只在引用类之前执行一次;另外,静态构造函数不能带有任何参数,而且一个类中只能有一个静态构造函数,它只能访问类的静态成员,不能访问实例成员。例如,定义一个静态构造函数,如下:

static Program() // 静态构造函数
{
    Console.WriteLine("我是静态构造函数~");
}

在类中,静态构造函数和无参的实例构造函数是可以共存的,因为静态构造函数是在加载类时执行,而实例构造函数是在创建类的对象时执行。

5、静态构造函数和实例构造函数的使用

class Program
{
   static Program() // 静态构造函数
   {
       Console.WriteLine("我是静态构造函数~");
   }

   public Program() // 实例构造函数
   {
       Console.WriteLine("我是实例构造函数~");
   }
   
   public static void Main(string[] args)
   {
       Program p1 = new Program(); // 创建类的对象p1
       Program p2 = new Program(); // 创建类的对象p2
   }
}

在这里插入图片描述
从上面这个案例,我们可以看出:静态构造函数只在引用类之前执行了一次,而实例构造函数则每创建一个对象都会执行一次。

二、析构函数

1、析构函数的概念

析构函数与构造函数相反,当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。

2、析构函数的定义

通过上面的概念,我们已经明确:析构函数主要用来释放对象资源,.NET Framework类库有垃圾回收功能,当某个类的实例被认为是不再有效,并符合析构条件时,.NET Framework类库的垃圾回收功能就会调用该类的析构函数实现垃圾回收。析构函数是以“~”来命名的,还是通过上面这个案例,我们为其添加析构函数,如下:

~Program() // 析构函数
{
    Console.WriteLine("析构函数自动调用了~");
}

在这里插入图片描述
注意:严格来说,析构函数是自动调用的,不需要开发人员显示定义。如果需要定义析构函数,一个类中只能定义一个析构函数。

构造函数和析构函数是类中比较特殊的两种成员函数,主要用来对对象进行初始化和释放对象资源。一般来说,对象的生命周期从构造函数开始,以析构函数结束。

3、析构函数的注意项

  1. 不能在结构中定义析构函数。只能对类使用析构函数。
  2. 一个类只能有一个析构函数。
  3. 无法继承或重载析构函数。
  4. 无法调用析构函数。它们是被自动调用的。
  5. 析构函数既没有修饰符,也没有参数。

4、析构函数的调用

  1. 垃圾回收器决定了析构函数的调用,我们无法控制何时调用析构函数。
  2. 垃圾回收器检查是否存在应用程序不再使用的对象。如果垃圾回收器认为某个对象符合析构,则调用析构函数(如果有)并回收用来存储此对象的内存。
  3. 程序退出时会调用析构函数。
  4. 我们可以通过调用Collect强制进行垃圾回收,但是请不要这样做,因为这样做可能导致性能问题。

三、构造函数与析构函数区别

  1. 构造函数和析构函数是类中比较特殊的两种成员函数。
  2. 构造函数是在创建对象时,使用给定的值将对象初始化。
  3. 析构函数用于释放一个对象。在对象删除前,使用析构函数做一些清理工作,它与构造函数的功能正好相反。
  4. 对象的生命周期从构造函数开始,从析构函数结束。
  5. 如果一个类含有构造函数,在实例化该类的对象时就会被调用。如果含有析构函数,则会在销毁对象时调用。
  6. 构造函数的名字与类名相同,析构函数的名字也跟类名相同,不过析构函数要在名字前加一个波浪号“~”
  7. 一个类中只能有一个析构函数,并且无法调用析构函数,它是被自动调用的。
  8. 当退出含有该对象的成员时,析构函数会自动释放这个对象所占用的空间,所以说析构函数是GC自动调用的,不是开发人员所控制的。
  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值