Delphi [델파이 문법] 클래스와 객체 #11
2012.05.31 19:13
소멸자
소멸자는 호출한 객체를 소멸하고 그 메모리를 해제하는 특수한 메소드입니다. 소멸자 선언 은 프로시저 선언과 비슷하지만 destructor로 시작합니다. 예를 들면 다음과 같습니다.
소멸자는 기본인 register 호출 규칙을 사용해야 합니다. 클래스는 두 개 이상의 소멸자를 가 질 수 있지만, 각 클래스는 상속된 Destroy 메소드를 오버라이드하고 다른 소멸자는 선언하 지 않는 것이 좋습니다.
소멸자를 호출하려면 인스턴스 객체를 참조해야 합니다. 예를 들면 다음과 같습니다.
소멸자가 호출되면 가장 먼저 소멸자 구현에서 지정된 동작들이 실행됩니다. 일반적으로 포 함된 모든 객체를 소멸하고 객체에 의해 할당되었던 리소스를 해제하는 작업들입니다. 다음 으로 객체에 할당되었던 메모리가 해제됩니다.
소멸자 구현의 예는 다음과 같습니다.
소멸자 구현의 마지막 동작은 일반적으로 상속된 소멸자를 호출하여 객체의 상속된 필드를
소멸하는 것입니다.
객체를 생성하는 중에 예외가 발생하는 경우 Destroy가 자동으로 호출되어 정상적으로 생성 되지 않은 객체를 제거합니다. 이는 불완전하게 생성된 객체를 제거하는 코드가 Destroy에 구현되어 있어야 한다는 것을 의미합니다. 생성자는 다른 동작을 실행하기 전에 새 객체의 필드를 0 또는 빈 값으로 설정하기 때문에, 불완전하게 생성된 객체의 클래스 타입 및 포인 터 타입 필드는 항상 nil입니다. 그러므로 소멸자는 클래스 타입 또는 포인터 타입 필드를 작 업하기 전에 nil인지 확인해야 합니다.
Destroy 대신 Free 메소드(TObject에서 정의)를 호 출하면 객체를 소멸하기 전에 내부적으로 자동으로 nil 값인지 확인하므로 편리합니다.
메시지 메소드
메시지 메소드는 동적으로 디스패치된 메시지에 대한 응답 동작을 구현합니다. 메시지 메소 드 문법은 모든 플랫폼에서 지원됩니다. VCL은 Windows 메시지에 응답하기 위해 메시지 메소드를 사용합니다. 메시지 메소드를 만들려면 메소드 선언에 message 지시어를 추가하 고, 그 뒤에 메시지 ID를 지정하는 1과 49151 사이의 정수 상수를 덧붙이면 됩니다. Win32 메시지의 경우에는 이 정수 상수(Win32 메시지 ID)들은 VCL 컨트롤의 메시지 메소드들을 위해 이미 정의되어 있으며, 해당하는 레코드 타입들과 함께 Messages 유닛에 정의되어 있 습니다. 메시지 메소드는 var 파라미터 하나만을 갖는 프로시저여야 합니다.
예를 들면, 다음과 같습니다.
메시지 메소드는 상속된 메시지 메소드를 오버라이드하기 위해 override 지시어를 포함할 필요가 없습니다. 사실, 메시지 메소드는 오버라이드하는 메소드와 같은 메소드 이름을 가질 필요도 없습니다. 오직 메시지 ID에 따라 메소드가 응답할 메시지와 오버라이드하는 것인지 의 여부가 결정됩니다.
메시지 메소드의 구현
메시지 메소드의 구현은 다음 예제에서와 같이 상속된 메시지 메소드를 호출할 수 있습니다.
메시지 메소드에서의 inherited 문은 클래스 계층에서 역으로 검색하여 현재 메소드와 같은 ID를 갖는 첫 메시지 메소드를 호출하고, 자동으로 메시지 레코드를 전달합니다. 조상 클래 스들이 모두 해당 메시지 ID에 대한 메시지 메소드를 구현하지 않은 경우, inherited는 TObject에서 정의된 DefaultHandler 메소드를 호출합니다.
TObject에 있는 DefaultHandler의 구현에서는 아무런 동작도 실행하지 않고 그냥 리턴됩 니다. DefaultHandler를 오버라이드하면 클래스는 자체적으로 기본 메시지 처리를 구현할 수 있습니다. 컨트롤의 DefaultHandler 메소드는 Win32 API의 DefWindowProc 함수를 호출합니다.
메시지 디스패칭
메시지 핸들러는 직접 호출되는 일은 거의 없습니다. 대신, TObject에서 상속된 Dispatch 메소드를 사용하여 메시지가 객체에 디스패치됩니다.
Dispatch에 전달된 Message 파라미터는 레코드로서, 첫 필드가 메시지 ID를 가진 Word 타입이어야 합니다. Dispatch는 클래스 계층에서 역으로 검색하여(호출된 객체의 클래스에서 시작) 전달된 ID 에 해당하는 처음으로 발견된 메시지 메소드를 호출합니다. 지정 ID에 대한 메시지 메소드 가 발견되지 않으면 Dispatch는 DefaultHandler를 호출합니다.