본문 바로가기
Delphi/클래스

클래스 참조(Class Reference)와 가상 생성자를 이용한 동적 객체 생성

by MonoSoft 2026. 3. 25.
728x90
반응형

클래스 참조(Class Reference)와 가상 생성자를 이용한 동적 객체 생성

델파이의 강력한 특징 중 하나는 클래스 자체를 변수에 저장할 수 있는 
클래스 참조(Class Reference) 타입입니다. 
class of TObject 형태의 타입을 정의하면, 런타임에 어떤 클래스를 
생성할지 결정할 수 있습니다. 
이때 부모 클래스에서 생성자를 virtual로 선언하면, 
실제 저장된 하위 클래스의 생성자가 호출되어 다형성을 
디자인 타임이 아닌 실행 시점에 완벽하게 구현할 수 있습니다.

program ClassReferenceExample;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  // 1. 베이스 클래스 정의
  TBaseMessage = class
  public
    // 가상 생성자 선언 (중요!)
    constructor Create; virtual;
    procedure ShowType; virtual; abstract;
  end;

  // 2. 클래스 참조 타입 정의
  TBaseMessageClass = class of TBaseMessage;

  // 3. 하위 클래스 구현들
  TErrorMessage = class(TBaseMessage)
  public
    constructor Create; override;
    procedure ShowType; override;
  end;

  TWarningMessage = class(TBaseMessage)
  public
    constructor Create; override;
    procedure ShowType; override;
  end;

{ TBaseMessage, TErrorMessage, TWarningMessage 구현부 }

constructor TBaseMessage.Create; begin end;

constructor TErrorMessage.Create;
begin
  Writeln('Error 객체가 메모리에 할당되었습니다.');
end;

procedure TErrorMessage.ShowType;
begin
  Writeln('결과: 이것은 에러 메시지 객체입니다.');
end;

constructor TWarningMessage.Create;
begin
  Writeln('Warning 객체가 메모리에 할당되었습니다.');
end;

procedure TWarningMessage.ShowType;
begin
  Writeln('결과: 이것은 경고 메시지 객체입니다.');
end;

var
  MsgClass: TBaseMessageClass; // 클래스를 담는 변수
  MsgInstance: TBaseMessage;   // 생성된 인스턴스를 담는 변수
begin
  // 런타임 조건에 따라 클래스 타입을 결정 (예제에서는 하드코딩)
  Writeln('--- 첫 번째 테스트: Error ---');
  MsgClass := TErrorMessage; 
  MsgInstance := MsgClass.Create; // 클래스 참조 변수를 통해 생성
  MsgInstance.ShowType;
  MsgInstance.Free;

  Writeln(sLineBreak + '--- 두 번째 테스트: Warning ---');
  MsgClass := TWarningMessage;
  MsgInstance := MsgClass.Create; 
  MsgInstance.ShowType;
  MsgInstance.Free;

  Readln;
end.

실행 결과
--- 첫 번째 테스트: Error ---
Error 객체가 메모리에 할당되었습니다.
결과: 이것은 에러 메시지 객체입니다.

--- 두 번째 테스트: Warning ---
Warning 객체가 메모리에 할당되었습니다.
결과: 이것은 경고 메시지 객체입니다.

class of TBaseMessage: 이 선언은 TBaseMessage 클래스나 
그 자식 클래스들을 값으로 가질 수 있는 메타 클래스 타입을 만듭니다.

constructor Create; virtual;: 생성자를 가상(virtual)으로 선언하지 않으면, 
클래스 참조 변수로 Create를 호출할 때 항상 
부모인 TBaseMessage의 생성자만 호출됩니다. 
override된 자식의 생성자를 부르기 위해 필수입니다.

팩토리 패턴(Factory Pattern)을 구현하거나, 
플러그인 시스템에서 클래스 이름만 가지고 
객체를 동적으로 생성할 때 매우 유용합니다.

델파이의 VCL 컴포넌트 라이브러리 자체가 
이 방식을 사용합니다. 
폼 디자이너에서 버튼을 배치하면 델파이는 내부적으로 
TButtonClass = class of TButton과 같은 
참조를 사용하여 스트림으로부터 객체를 동적으로 생성해냅니다.

728x90
반응형

댓글