C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

컴포넌트/라이브러리
Delphi/C++Builder Programming Components&Libraries
[557] 델파이판 AutoPtr
김태선 [cppbuilder] 12381 읽음    2009-02-15 16:04
델파이에서 모든 클래스는 사실상 포인트로 다루어집니다.
var
  list : TStringList;

list := TStringList.Create;

이렇게 되면
list 는 TStringList의 인스턴스에 대한 포인트 역할을 합니다.
문법상 뚜렷하게 포인트와 객체의 인스턴스를 구분짓는 C++과는 달리
델파이에서는 내부적으로는 포인트로 알아서 처리되지만 겉보기는 그냥 실제 객체로 다루고 있는 것처럼 보입니다.

그런데 델파이 인스턴스 만들때 제약 사항이 있습니다.
바로 클래스의 인스턴스는 모두 힙에 생성되어야 하며, 스택에는 생성될 수 없다는 것입니다.
이로 인해 인스턴스를 Create 해주면 짝을 맞춰 명시적으로 Free 해줘야 하는 수고를 해야 합니다.
이는 델파이 사용자라면 늘상 하는 일이니 아무런 불편이 되지 않을지 모릅니다.
그러나 C++를 쓰던 입장에서 보면 대단히 불편한 부분이 아닐 수 없습니다.
스택에 인스턴스를 생성하지 못하는 것은 컴파일러 구조상 어쩔수 없다고 한다면,
최소한 명시적으로 객체를 해제해주는 것만은 생략할 수 있지 않을까 해서 예전에 자료를 찾아 봤는데,
마침 IInterface의 인스턴스가 지역 객체로 동작하는 특성을 이용해서, 구현한 사례가 있더군요.

JCL에 있던 Guard를 간략하게 바꾼, 델마당의 프리맨님이 올린 Guard 가 그것입니다.
출처:
http://www.delmadang.com/community/bbs_view.asp?bbsNo=3&bbsCat=0&st=S&keyword=guard&indx=196963&keyword1=guard&keyword2=&page=1

C++에서는 이러한 것을 보통 스마트포인트 또는 AutoPtr 이라고 하므로,
직관성을 높이기 위해 명칭을 AutoPtr 로 변경했습니다.
델파이 프로그램 때 이를 적용하면 한결 편리합니다. 객체의 해제에 대한 신경을 안써도 되기 때문입니다.

예제.
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uAutoPtr, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  list: TStringList;
  list2: TStringList;
begin
  list := TStringList.Create;
  AutoPtr(list2, TStringList.Create);

  try
    list.Add('우리는 민족중흥의');
    list.Add('역사적 사명을 띄고 이땅에 태어났다.');
    Memo1.Lines := list;

    list2.Add('조상의 빛난 얼을 오늘에 되살려');
    list2.Add('IT 최강국을 만들자.');
    Memo2.Lines := list2;
  finally
    list.Free;
  end;
  // list2는 자동 free 된다.
  // 위처럼 try finally 블럭을 써서 명시적으로 Free 해줘야 하는 수고를 안해도 되며
  // 이 함수를 어떤 식으로 벗어나던지 벗어날때 자동으로 Free 된다.
end;

end.


AutoPtr 유닛 소스
---------------

unit uAutoPtr;

interface

function AutoPtr(out Reference; Instance: TObject): IUnknown;

implementation

type
  TGuardObject = class(TInterfacedObject)
  private
    FInstance: TObject;
  public
    constructor Create(Instance: TObject);
    destructor Destroy; override;
  end;

{ TGuardObject }

constructor TGuardObject.Create(Instance: TObject);
begin
  FInstance:= Instance;
end;

destructor TGuardObject.Destroy;
begin
  FInstance.Free;
  inherited;
end;

function AutoPtr(out Reference; Instance: TObject): IUnknown;
begin
  Result := TGuardObject.Create(Instance);
  TObject(Reference) := Instance;
end;

end.
꾸루미 [ziron]   2009-02-21 02:45 X
와우 ~
정말 유용하네요 ^^ 코드도 깔끔해지구 감사합니다.

+ -

관련 글 리스트
557 델파이판 AutoPtr 김태선 12381 2009/02/15
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.