Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

nomad-programmer

[Programming/C#] 생성자와 소멸자 본문

Programming/C#

[Programming/C#] 생성자와 소멸자

scii 2020. 9. 8. 01:52

객체는 생성자에 의해 만들어지고 소멸자에 의해 사라진다.

생성자

생성자는 클래스와 이름이 같고, 반환 형식이 없다. 생성자의 임무는 단 한 가지, 해당 클래스의 객체를 생성하는 것뿐이다. 그러기에 반환할 것이 없다.

클래스를 선언할 때 명시적으로 생성자를 구현하지 않아도 컴파일러에서 생성자를 만들어준다 (이런 생성자를 기본 생성자라 한다). 
객체를 다루다 보면 객체를 생성하는 시점에 객체의 필드를 원하는 값으로 초기화하고 싶을 때가 이런 작업을 할 수 있는 최적의 장소가 바로 객체를 생성하기 위해 호출하는 메소드인 생성자이다.

생성자도 오버로딩이 가능하다

 

소멸자

종료자의 이름은 클래스 이름 앞에 ~를 붙인다. 그리고 소멸자는 생성자와는 달리 매개 변수도 없고, 한정자도 사용하지 않는다. 또한 여러 버전의 소멸자를 만드는 오버로딩도 불가하며 직접 호출도 할 수 없다. 

CLR의 가비지 컬렉터가 객체가 소멸되는 시점을 판단해서 소멸자를 호출한다.

소멸자를 가급적 사용하지 말자.

그 이유는 일단 CLR의 가비지 컬렉터가 언제 동작할지 예측할 수 없다. CLR은 치워야 할 쓰레기가 일정 양에 이르러야 동작하기 때문이다. 문제는 쓰레기가 차오르는 시간을 정확하게 알 수 없고, 따라서 가비지 컬렉터가 동작할 시점도 알 수 없다는 것이다. 객체의 사용이 끝난 직후가 될 수도 있고 10분 후가 될 수도 있다. 중요한 자원을 소멸자에게 해제하도록 놔뒀다가는 얼마 가지 않아 자원이 금새 부족해지는 현상을 겪게 될지 모른다.

그 뿐만 아니라 명시적으로 소멸자가 구현되어 있으면 가비지 컬렉터가 object로부터 상속받은 Finalize() 메소드를 클래스의 족보를 타고 올라가며 호출하기 때문에 대개의 경우 응용 프로그램의 성능의 저하만 가져올 확률이 높다.

소멸자를 구현하지 말아야 할 가장 중요한 이유

그것은 바로 CLR의 가비지 컬렉터는 인간보다 훨씬 더 똑똑하게 객체의 소멸을 처리할 수 있다는 것이다.
생성은 생성자에게, 뒷처리는 가비지 컬렉터에게 맡기는 편이 좋다.

 

생성자 & 소멸자의 예제

using System;

namespace CSharpExample
{
    class Cat
    {
        public string Name;
        public string Color;

        // 생성자
        public Cat()
        {
            Name = "";
            Color = "";
        }

        // 생성자 오버로딩
        public Cat(string _name, string _color)
        {
            Name = _name;
            Color = _color;
        }

        // 소멸자
        ~Cat()
        {
            Console.WriteLine($"{Name}: 잘가");
        }

        public void Meow()
        {
            Console.WriteLine($"{Name}: 야옹~");
        }
    }

    class MainApp
    {
        static int Main(string[] args)
        {
            Cat kitty = new Cat("키티", "하얀색");
            kitty.Meow();
            Console.WriteLine($"{kitty.Name}: {kitty.Color}");

            Cat nero = new Cat(_name: "네로", _color: "검은색");
            nero.Meow();
            Console.WriteLine($"{nero.Name}: {nero.Color}");

            return 0;
        }
    }
}

/* 결과

키티: 야옹~
키티: 하얀색
네로: 야옹~
네로: 검은색
네로: 잘가
키티: 잘가

*/
Comments