안녕하세요. 제가 Free와 Destroy의 차이가 궁금해서 다음과 같은 간단한 프로그램을 만들어 보았습니다.
TTestClass = class(TObject)
..
end;
Constructor TTestClass.Create;
begin
ShowMessage('Constructor: Create');
end;
Destructor TTestClass.Destroy;
begin
ShowMessage('Destructor: Destroy');
end;
보시다시피 생성자와 파괴자에서 ShowMessage를 호출하는데요,
procedure TForm1.Button2Click(Sender: TObject);
var
TestClass: TTestClass;
begin
TestClass := TTestClass.Create;
TestClass.Destroy; // 요렇게 하면 메시지 창이 뜹니다.
TestClass.Free; // 요렇게 하면 메시지 창이 뜨지 않습니다.
end;
위에서 주석으로 단것 처럼 Destroy를 사용해야 파괴자가 호출됩니다.
그런데 델파이 핼프를 보면 'Free와 Destroy의 차이점은 Free는 오브젝트가 nil이더라도 에러를 일으키지않는 것이고, 따라서 Destroy를 직접사용하지 말고 Free를 써야한다. Free는 자동으로 파괴자를 호출한다'라고 써 있습니다. Free가 파괴자를 호출한다면 당연히 메시지 창이 떠야하는 것 아닌가요?
초보적인 질문이지만 고수분들께서 알려주신다면 정말 감사하겠습니다.
먼저 알아야 할것은 Free라는 메소드 입니다.
Free는 TObject의 멤버함수 입니다.
Free가 TTestClass 에 따로 정의 되지 않았으면 부모 객체인 TObject의 Free가 실행됩니다.
메모리에는 이렇게 저장되죠
---TObject ---
---
Destory
Free
----------------
--- TestClass에 추가된 부문---
---
Destory
----------------
TestClass.free 하면 일련의 동작은
TObject의 Free을 실행하며 TObject의 Destory를 실행합니다.
즉 TestClass의 Destory를 실행하는 것이 아니죠
우리가 델파이 헬프를 보면 Destory는 끝에 Tobject에서 상속 받은것은 override 다 붙죠
일반적으로 정의시 Destructor Destroy; override; 정의하죠
나머지는 클래스에 대해서 알아보세요 특히 override, overload에 대해서요
이 이상은 강의실에서 알아 보심이 옳겠네요
<!--CodeS-->
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TTestClass = class(TObject)
public
Destructor Destroy; override;
end;
TTestClass2 = class(TTestClass)
public
Destructor Destroy;
end;
TTestClass3 = class(TTestClass)
public
Destructor Destroy; override;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Destructor TTestClass.Destroy;
begin
ShowMessage('Destructor: Destroy');
end;
Destructor TTestClass2.Destroy;
begin
ShowMessage('Destructor: Destroy2');
end;
Destructor TTestClass3.Destroy;
begin
ShowMessage('Destructor: Destroy3');
//inherited;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
mTest : TTestClass;
mTest2 : TTestClass2;
mTest3 : TTestClass3;
begin
mtest := TTestClass.Create;
mtest.free;
mTest2 := TTestClass2.Create;
mtest2.free;
mTest3 := TTestClass3.Create;
mtest3.free;
end;
end.
<!--CodeE-->
이것을 보시고 어떤 현상이 일어나는지
중간에 inherited; 이것을 넣어서 어떤식으로 변화하는 지 확인해보세요