Unity/c#

4. C# 생성자(Constructor)와 소멸자(Destructor)

RongBee 2023. 8. 6. 20:50

무언가를 생성할 때 자동으로 호출되는 메서드가 있다.

 

바로 생성자 메서드(Constructor Method)이다.

 

인스턴스 생성자의 생성  조건은 이러하다.

 

1. 이름이 클래스 이름과 같다.

 

2. 접근 제한자는 public이다.

 

3. 반환과 관련된 선언을 하지 않는다.

 

 

우선 생성자로 private 생성자에 대해 알아보자.

 

class Program
{
    class Hidden
    {
        private Hidden() {}
    }
    
    static void Main(string[] args)
    {
        Hidden hidden = new Hidden();
    }
}

 

생성자로 클래스의 인스턴스를 만들 수 없게 할 때는 private 생성자를 사용한다.

 

 

class Sample
{
    public static int value;
    
    static Sample()
    {
        value = 10;
        Console.WriteLine("정적 생성자 호출");
    }
}

 

정적 요소를 초기화할 때 사용한다.

 

접근 제한자를 사용하지 못하며, 매개변수를 사용하지 못한다.

 

정적 요소를 사용할 때 또는 인스턴스를 생성하는 초기 시점에 한번만 호출된다.

 

그리고 해당 클래스와 관련된 요소를 처음 사용하는 시점에 자동 호출된다.(별도로 호출 불가)

 

 

 

 

정적 멤버만 가지고 있을 때, 팩토리 메서드라는 디자인 패턴에서

 

팩토리 메서드로만 인스턴스를 생성하게 하고 싶을 때 사용된다.

 

우선 팩토리 메서드는 생성 패턴으로 객체를 생성할 때 어떤 클래스의 인스턴스를 만들지 서브 클래스에서 결정하게 된다.

 

즉 인스턴스 생성 권한을 서브 클래스에게 준다.

 

부모 추상 클래스는 인터페이스에만 의존하고 실제로 어떤 구현 클래스를 호출할 지는 서브 클래스에서 구현한다.

 

 

 

 

 

생성자가 있다면 소멸자라는 개념도 존재한다.

 

소멸자는 인스턴스가 소멸될 때 호출된다.

 

변수의 불(不)사용이 확실할 때 객체를 소멸시키며 소멸자를 호출한다.(객체 소멸시기는 명확하지 않다.)

 

 

소멸자의 생성 규칙

 

1. 이름은 클래스 이름 앞에 ~ 기호 붙어있다.

 

2. 접근 제한자를 사용하지 않는다.

 

3. 반환과 관련된 선언을 하지 않는다.

 

4. 매개변수와 관련된 선언을 하지 않는다.

 

5. 하나의 클래스에는 하나의 소멸자만 존재한다.

 

namespace Test
{

    using System;

    public class MyClass
    {
        private string resourceName;

        // 생성자
        public MyClass(string name)
        {
            resourceName = name;
            Console.WriteLine($"Creating MyClass with resource: {resourceName}");
        }

        // 소멸자
        ~MyClass()
        {
            // 관리되지 않은 리소스 정리를 수행한다.
            Console.WriteLine($"Destructing MyClass and releasing resource: {resourceName}");
        }
    }

    public class Program
    {
        public static void Main()
        {
            // MyClass 인스턴스 생성
            MyClass myObject = new MyClass("Resource1");

            // 가비지 콜렉터 실행
            GC.Collect();

            // 출력을 기다린다.
            System.Threading.Thread.Sleep(1000);
            Console.WriteLine("End of Main");
        }
    }
}

 

 

이렇게 하게 된다면 생성자 -> Main함수 -> 소멸자 순으로 출력이 되는 것을 볼 수 있다.

 

생성자 및 소멸자의 호출 순서는 인스턴스가 생성된 후 소멸되는 방식이다.

 

그래서 인스턴스 생성자에서 소멸자 순으로 출력이 되는 것이다.

 

 

using System;

    public class BaseClass
    {
        public BaseClass()
        {
            Console.WriteLine("Constructor of BaseClass called.");
        }

        ~BaseClass()
        {
            Console.WriteLine("Destructor of BaseClass called.");
        }
    }

    public class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("Constructor of DerivedClass called.");
        }

        ~DerivedClass()
        {
            Console.WriteLine("Destructor of DerivedClass called.");
        }
    }

    public class Program
    {
        public static void Main()
        {
            DerivedClass derivedObject = new DerivedClass();

            GC.Collect();

            System.Threading.Thread.Sleep(1000);
            Console.WriteLine("End of Main");
        }
    }

 

호출 순서에 관한 생성자에 특징은 기본 클래스에서 파생 클래스로 하향식 접근 방식으로 호출된다.

 

또 모든 기본 클래스 생성자가 실행된 후 파생 클래스의 생성자가 호출된다.

 

반대로 소멸자는 기본 클래스에서 파생 클래스로 하향식 방식으로 호출되지 않고,

 

파생 클래스의 소멸자가 먼저 호출된 후 기본 클래스의 소멸자가 호출되는 상속 계층 구조에서 호출된다.

 

 

 

Referencehttps://bcp0109.tistory.com/367