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

C++빌더 강좌/문서
C++Builder Programming Tutorial&Docments
[104] [KTS의 C++빌더] VCL Style 클래스의 자동화를 위한 스마트 TTVCL, TTClass
김태선 [cppbuilder] 17205 읽음    2006-06-09 12:48
//---------------------------------------------------------------------------
// 김태성의 C++빌더 : VCL Style 클래스의 자동화를 위한 스마트 TTVCL, TTClass
//---------------------------------------------------------------------------

VCL Style 클래스는 반드시 힙에 생성해야 한다. 그래서 반드시
XClass  *p = XClass(args);
식으로 생성해야 한다. 그리고 사용뒤에는 반드시
delete p;
로 소멸시켜야만 한다.
그냥 보통의 C++ 클래스처럼
XClass  xclass;
식으로 생성이 되지 않는다.
이것이 C++ 프로그래머에겐 조금 불편한 사항 중에 하나이다.

얼마전에 필자는, 이러한 불편을 개선하고 프로그래밍에서의 객체처리 자동화를 지원하기 위해
new 가 아닌  클래스 선언으로만 생성할 수 있게 약간의 래핑을 한
KTStringList 와 KTList 를 소개한 바가 있다.
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=612

또한, 이전 강좌에서는 Tnew 클래스를 소개하여,
일반 변수나 클래스의 배열을 지역변수 쓰듯이 사용할 수 있게 했다.
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tutorial&no=103

즉 여러가지 경우에 있어 delete 로 짝을 맞춰 신경써서 지워줄 필요없이
자동으로 객체가 소멸하게 함으로써, 보다 안전하고 delete 신경쓰지 않는 편리한 프로그래밍을 가능하게 했다.
예외가 발생해 루틴의 중간에 함수를 빠져나갈 때를 대비하지 않은 경우라도
안전하게 소멸되기 때문에, 그 가치는 제법 있다고 하겠다.

오늘은 이를 일반적인 컴포넌트와 폼 그리고 VCL Style 클래스에 일반적으로 적용할 수 있는
템플릿 클래스를 제작해 소개한다.


먼저 컴포넌트와 폼 등을 정적으로 생성하여 사용할 수 있는 TTVCL을 소개한다.
모든 컴포넌트와 폼등은
TForm1 *form = new TForm1(Application);
TButton  *btn = new TButton(form);
식으로 동적으로 생성되어야 한다.
이를 delete 가 없는 스마트 클래스화한 것이 바로 TTVCL 이다.

그러므로 정적으로 다음과 같이 생성 할수 있다.
TTVCL<TForm1>  form(Application);
TTVCL<TButton>  Btn1(form);
이 두 줄은 위의 두 줄과 같다.
하지만 객체를 메모리에서 지우기 위해 delete 할 필요없다.
자동으로 소멸하기 때문이다.

여기서 하나, 언어 표현에 약간의 정확지 않은 부분이 있다.
사실 정적이라는 표현은 new 로 동적으로 생성하는 것에 대한 대비표현일뿐
여기서는, 사실은 동적으로 생성하고 다루기만 정적인 인스턴스인양하는 것 뿐이다.

다음은 TTVCL 소스이다.

//---------------------------------------------------------------------------
// 일반적인 VCL 스타일 클래스를 정적으로 생성하는 템플릿 클래스
// 단, 생성자의 인자를 TComponent 로 하는 클래스이어야 함.
// 모든 컴포넌트와 폼 등의 수많은 VCL Style 클래스가 해당됨.

template<class T>
class TTVCL
{
public:
    T    *p;
public:
    TTVCL(TComponent *Owner)
    {
        p = new T(Owner);
    }
    ~TTVCL()
    {
        delete p;
    }
    T* operator->() { return p; }
    T& operator*()  { return *p; }
    operator T*()   { return p; }
};
//---------------------------------------------------------------------------

정말 간단하다.

그런데 VCL Style 클래스에는 TComponent를 생성 인자로 하는 것 뿐만 아니라
인자 자체가 없이 사용되는 것도 있다.
TStringList, TList 등과 같은 것들이다.

이의 정적인 생성을 지원하기 위한 템플릿클래스가 바로 아래의 TTClass 이다.

이미 필자는 KTStringList 와 KTList 를 소개하여
정적 객체로 사용할수 있게 했지만,
여기서는 그것을 일반화 했다. 즉 인자가 없는 모든 VCL 클래스에 다 사용할 수 있게 한 것이다.
물론 편의성은 KTStringList, KTList가 조금 더 있지만
여기서는 일반화된 템플릿 클래스이므로 다른 VCL 클래스에 적용해서 사용할 수 있다.

그래서
TTClass<TStringList> strongs;
TTClass<TList> lists;
식으로 사용 가능하다.


아래는 소스이다.
//---------------------------------------------------------------------------
// 일반적인 VCL 스타일 클래스를 정적으로 생성하는 템플릿 클래스
// 생성자의 인자를 가지지 않는 클래스만 사용할 수 있다.
// TStringList, TList 등...

template<class T>
class TTClass
{
public:
    T    *p;
public:
    TTClass()
    {
        p = new T;
    }
    ~TTClass()
    {
        delete p;
    }
    T* operator->() { return p; }
    T& operator*()  { return *p; }
    operator T*()   { return p; }
};
//---------------------------------------------------------------------------
이것 역시 정말 간단하다.

그런데 TTVCL 과 TTClass 구조가 거의 같다.
다른 점이라면 생성자 부분만 틀리다.
이 둘을 통합해서 처리할 방법이 없을까?
안타깝게도 C++의 템플릿의 구조 문제로 통합은 되지 않는다.


보통 템플릿 클래스는 실제 사용되어져야만 컴파일 되어 약간의 컴파일 시간을 더 소요하고,
컴파일된 코드는 지정한 클래스의 형별로 바이너리로 생성되므로,
실행화일 크기를 조금 더 증가 시킨다는 것은 상식이다.
그러나, C++빌더 컴파일러는 우수해서,
아주 복잡한 큰 템플릿 클래스가 아니라면 컴파일 시간은 크게 소요하지 않고,
위 같이 간단한 템플릿 클래스인 경우는 실행화일 크기에 미치는 영향도 아주 작다.


아래는 사용 예이다.
//---------------------------------------------------------------------------
// 같은 폼을 하나 더 만드는 예제

void __fastcall TForm1::Button3Click(TObject *Sender)
{
    TTVCL<TForm1>  form(Application);
    form->Left = 0;
    form->Top = 0;

    TTVCL<TButton>  Btn1(form);
    Btn1->Parent = form;
    Btn1->Top = 100;
    Btn1->Left = 100;
    Btn1->Width = 200;
    Btn1->Height = 40;
    Btn1->Caption = "동적 생성 버턴입니다.";
    form->ShowModal();

    // 정적으로 생성된 객체는 마지막에 생성된 것이 먼저 사라진다.
    // 위에서 Btn1 이 먼저 소멸되고 다음 form 이 소멸된다.
}
//---------------------------------------------------------------------------
// 패널을 생성해 잠시 윈도를 가리는 예제

void __fastcall TForm1::Button4Click(TObject *Sender)
{
    TTVCL<TPanel> a(this);
    a->Parent = this;
    a->Align = alClient;
    a->Color = clWhite;
    a->Caption = "패널로 잠시 가렸습니다.";
    Update();   
    MessageBox(Handle, "확인.", "pause", MB_OK);
}
//---------------------------------------------------------------------------
// 메모에 TStrings 표시 예제.

void __fastcall TForm1::Button5Click(TObject *Sender)
{
    TTClass<TStringList> s;
    s->Add("테스트입니다");
    s->Add("1");
    s->Add("2");
    s->Add("4");
    s->Add("끝");
    s->Insert(3, "3 번째");
    Memo1->Lines = s;
}
//---------------------------------------------------------------------------

아주 약간의 프로그래밍의 편의성이 증가할 것이지,
생각보다 도움이 될지는 각자가 판단하기 바란다.

중요한 것은 이러한 자동화는 버그를 줄이고 편리한 프로그래밍 환경을 만드는데 도움이 된다는 사실이다.


[첨부파일]

첨부된 TTClass.h 는 두개의 템플릿 클래스인 TTVCL, TTClass 뿐만 아니라
이전에 소개한 Tnew 까지 한데 넣었다.
아무래도 연관성이 높아 한데 두는게 좋을것 같아서이다.




//---------------------------------------------------------------------------
// 김태성 cppbuilder@naver.com
// 이 강좌는 아무 곳에나 비상업적인 용도에 한해 내용 변경 없이 원래의 출처를 명시하여
// 배포할 수 있습니다. 단, 필자의 이메일로 게제 사실을 통보해야 합니다.
//---------------------------------------------------------------------------

+ -

관련 글 리스트
104 [KTS의 C++빌더] VCL Style 클래스의 자동화를 위한 스마트 TTVCL, TTClass 김태선 17205 2006/06/09
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.