C#에서 객체의 생명 주기를 관리하는 핵심 요소인 생성자(Constructor)와 소멸자(Destructor)는 이름만 들으면 비슷해 보이지만, 호출 시점과 역할이 완전히 다릅니다. 이 글에서는 두 개념의 차이점을 예제 코드와 함께 자세히 살펴보겠습니다.
C# 생성자(Constructor)란?
생성자는 클래스의 새로운 객체가 생성될 때마다 자동으로 실행되는 특수한 멤버 함수입니다. 주로 객체를 초기화하거나 필요한 리소스를 준비하는 용도로 사용됩니다.
생성자의 특징은 다음과 같습니다.
- 클래스 이름과 정확히 동일한 이름을 가져야 합니다.
- 반환 타입이 없습니다. (void조차 명시하지 않습니다.)
- 객체 생성 시점(new 키워드 사용 시)에 자동으로 호출됩니다.
- 매개변수를 가질 수 있어 오버로딩이 가능합니다.
클래스 이름이 Demo라면 생성자는 아래와 같이 선언합니다.
class Demo {
public Demo() {}
}
생성자 예제
using System;
namespace LineApplication {
class Line {
private double length; // 선의 길이
public Line() {
Console.WriteLine("객체가 생성되고 있습니다");
}
public void setLength( double len ) {
length = len;
}
public double getLength() {
return length;
}
static void Main(string[] args) {
Line line = new Line();
// 선 길이 설정
line.setLength(6.0);
Console.WriteLine("선의 길이 : {0}", line.getLength());
Console.ReadKey();
}
}
}
실행 결과
객체가 생성되고 있습니다 선의 길이 : 6
위 예제에서 new Line()으로 객체를 생성하는 순간 생성자가 호출되어 메시지가 출력된 것을 확인할 수 있습니다.
C# 소멸자(Destructor)란?
소멸자는 클래스의 객체가 범위(scope)를 벗어나 소멸될 때 실행되는 특수한 멤버 함수입니다. 객체가 사용하던 리소스를 정리하는 용도로 활용됩니다.
소멸자의 특징은 다음과 같습니다.
- 클래스 이름 앞에 틸드(~)를 붙인 이름을 사용합니다. (예: 클래스명이 Demo라면 ~Demo)
- 값을 반환할 수 없고, 매개변수도 가질 수 없습니다.
- 오버로딩이 불가능하며 클래스당 하나만 정의할 수 있습니다.
- 가비지 컬렉터(GC)에 의해 호출되므로 정확한 호출 시점을 예측하기 어렵습니다.
아래는 생성자와 소멸자를 함께 정의한 모습입니다.
public Demo() { // 생성자
Console.WriteLine("객체가 생성되고 있습니다");
}
~Demo() { // 소멸자
Console.WriteLine("객체가 삭제되고 있습니다");
}
소멸자 예제
using System;
namespace LineApplication {
class Line {
private double length; // 선의 길이
public Line() { // 생성자
Console.WriteLine("객체가 생성되고 있습니다");
}
~Line() { // 소멸자
Console.WriteLine("객체가 삭제되고 있습니다");
}
public void setLength( double len ) {
length = len;
}
public double getLength() {
return length;
}
static void Main(string[] args) {
Line line = new Line();
// 선 길이 설정
line.setLength(6.0);
Console.WriteLine("선의 길이 : {0}", line.getLength());
}
}
}
실행 결과
객체가 생성되고 있습니다 선의 길이 : 6 객체가 삭제되고 있습니다
프로그램이 종료되면서 객체가 소멸될 때 소멸자가 호출되어 마지막 메시지가 출력된 것을 볼 수 있습니다.
생성자와 소멸자의 차이점 비교
| 구분 | 생성자(Constructor) | 소멸자(Destructor) |
|---|---|---|
| 호출 시점 | 객체 생성 시 자동 호출 | 객체 소멸 시(GC에 의해) 호출 |
| 이름 규칙 | 클래스 이름과 동일 | 클래스 이름 앞에 ~(틸드) 붙임 |
| 매개변수 | 가질 수 있음 (오버로딩 가능) | 가질 수 없음 |
| 반환 값 | 없음 | 없음 |
| 주요 용도 | 객체 초기화, 리소스 할당 | 리소스 해제, 정리 작업 |
마무리
정리하면, 생성자는 객체가 태어날 때 초기화를 담당하고, 소멸자는 객체가 사라질 때 정리를 담당합니다. 다만 C#은 가비지 컬렉션 기반이기 때문에 소멸자의 호출 시점이 불확실하며, 확실한 리소스 해제가 필요하다면 IDisposable 인터페이스와 using 문을 활용하는 것이 권장됩니다.