|
네... 방태윤님말씀대로 하면 됩니다.
그런데 그 원인은 ....
TCustomForm에 있습니다.
public:
__fastcall virtual TCustomForm(Classes::TComponent* AOwner);
__fastcall virtual TCustomForm(Classes::TComponent* AOwner, int Dummy);
TCustomForm에 생성자에 위와같이 두가지 형태로 이미 존재합니다.
그런데 TCustomForm의 소스를 보면
constructor TCustomForm.Create(AOwner: TComponent); //생성자1
begin
GlobalNameSpace.BeginWrite;
try
CreateNew(AOwner); //생성자2
if (ClassType <> TForm) and not (csDesigning in ComponentState) then
begin
Include(FFormState, fsCreating);
try
if not InitInheritedComponent(Self, TForm) then
raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
finally
Exclude(FFormState, fsCreating);
end;
if OldCreateOrder then DoCreate;
end;
finally
GlobalNameSpace.EndWrite;
end;
end;
생성자1에서 생성자2를 호출합니다.
그런데
Form2의 오버라이드 한 생성자 형태가 CustomForm의 두번째 생성자와 형태가 똑같고
또한 Form2의 두번째생성자에서 Form의 첫번째 형태의 생성자를 호출하고있으니...
TCustomForm에서는 의 생성자에서는 두번째형태의 생성자를 다시 호출하고...
그러면 Virtual로 된 함수이니 실제함수이 TForm2의 두번째형태의 생성자를 호출하고...
그것이 무한 반복되어 stack over flow가 나는것입니다.
해결
방법1.
생성자를 오버라이드 할때 TComponent * Owner , Int ... 형의 생성자를 쓰지 않고
다른 형태로 바꿔쓴다..
방법2.
TForm2(TComponent* Owner, int inputValue); 형태로 쓸때
실제함수에서 TForm의 생성자를 호출할때도 두번째 형태의 함수를 호출한다.
__fastcall TForm2::TForm2(TComponent* Owner,int val)
: TForm(Owner,val) /// TForm(Owner) ==> TForm(Owner,val) 이런 형태로 호출하면...
{
ShowMessage("adfasdf");
}
그런데 이렇게 하면 폼의 모양이 이상하게 나옵니다.
왜 그런가하면....
위 TCustomForm의 두번째 생성자인 CreateNew
C++Builder에서는 (TComponent* Owner,int val) 형태의 생성자는
폼을 생성할때 리소스 파일을 참조하여 폼위에 올려진 Component를 생성해주지 않습니다.
다시 말하면 (TComponent* Owner,int val) 형태의 생성자는 *.dfm 의 리소스가 없이
오로지 Coding으로만 폼을 만들때 사용합니다.
코딩으로만 Form을 만들어서 TForm(TComponent* Owner) 형태의 생성자를 호출하면 에러가 납니다.
이럴때 TForm((TComponent* Owner , int val) 형태의 생성자를 호출하면...
에러없이 폼이 만들어지죠...
그러므로 결론을 지으면
1. 생성자의를 오버라이드 할때
그냥 방법1처럼 형태를 TComponent *Owenr , int 형 만 피하면 됩니다.
방태윤님 말처럼 순서만 바꿔도 해결되죠
2. 그리고 c++Builder나 Delphi에서 wizard로 폼을 만들지 않고
Coding으로만 Form-Class를 만들어서 폼을 생성하고자 한다면
TForm((TComponent* Owner , int val) 형태의 생성자를 만들어 호출해주시면 됩니다.
그럼...
방태윤 님이 쓰신 글 :
: 제대로 하신것 같습니다. 제가 해도 그렇게 할것입니다.
:
: 그런데 문제는 작동이 안된다는 것이지요,ㅋ
:
: __fastcall TForm2(TComponent* Owner, int inputValue);
:
: 이 부분을
:
: __fastcall TForm2(int inputValue,TComponent* Owner);
:
: 두 변수 순서를 바꾸어 보세요.
:
: 좀 황당하지만 그렇게 하면 됩띠다... 왜 그런지는 모르지만요.
:
: (빌더6 기준입니다)
: (bds2006도 그러네.ㅋ)
:
: 빌더초보 님이 쓰신 글 :
: : 고수님들 안녕하세요.
: :
: : 빌더를 접한지 얼마되지 않은 초보입니다.
: :
: : 폼 생성자의 오버로드 문제 때문에 이렇게 문의를 드립니다.
: :
: :
: : 보통 한 application에서 두개 이상의 폼을 생성하여 show를 시킬 때
: : 이렇게 썼었거든요.
: :
: : 1) File -> New -> Form 해서 새로운 폼을 하나 추가시킴
: :
: : 2) Project -> Options -> Forms 에서 새로 추가시킨 폼을
: : Auto-create forms: 에서 Available forms: 로 이동시킴
: :
: : 3) 원하는 곳에서 다음 구문을 추가하여 폼 생성함
: :
: : if( tempForm == NULL ) tempForm = new TtempForm(this);
: : tempForm->Show();
: :
: : 여태까지 이런식으로 새로운 폼을 생성 & Show 를 했습니다.
: :
: :
: :
: : 보통 폼의 생성자가
: : __fastcall TForm2(TComponent* Owner);
: :
: : 이렇게 되어있는데
: :
: :
: :
: : 저는
: : __fastcall TForm2(TComponent* Owner, int inputValue);
: :
: : 이런 형태를 가진 폼 생성자가 필요합니다.
: :
: :
: : 그래서 다음과 같이 했습니다.
: :
: : 1) File -> New -> Form 해서 새로운 폼을 하나 추가시킴
: :
: :
: :
: : 2) Project -> Options -> Forms 에서 새로 추가시킨 폼(Form2)을
: : Auto-create forms: 에서 Available forms: 로 이동시킴
: :
: :
: :
: : 3) Unit1.cpp 파일 상단에 다음 구문을 추가함
: :
: : #include <vcl.h>
: : #pragma hdrstop
: :
: : #include "Unit1.h"
: : #include "Unit2.h" ---> 새로 추가함.
: :
: :
: :
: : 4) Unit2.h 파일에 다음 구문을 추가함
: :
: : class TForm2 : public TForm
: : {
: : __published: // IDE-managed Components
: : private: // User declarations
: : public: // User declarations
: : __fastcall TForm2(TComponent* Owner);
: : __fastcall TForm2(TComponent* Owner, int inputValue); ---> 새로 추가한 내용
: : };
: :
: :
: :
: : 5) Unit2.cpp 파일에 다음 구문을 추가함
: : __fastcall TForm2::TForm2(TComponent* Owner, int inputValue)
: : : TForm(Owner)
: : {
: : ShowMessage(IntToStr(inputValue);
: : }
: :
: :
: :
: : 6) Form1 에 Button 콤퍼넌트를 추가시키고 다음과 같은 Click 이벤트를 추가함
: :
: : void __fastcall TForm1::Button1Click(TObject *Sender)
: : {
: : if( Form2 == NULL ) Form2 = new TForm2(this, 2);
: : Form2->Show();
: : }
: :
: :
: : 이렇게 해서 컴파일을 시키면 에러없이 컴파일이 완료됩니다.
: : 하지만 Form1에 있는 버튼을 누르면
: : 다음과 같은 에러창이 뜹니다.
: :
: :
: : [Debugger Exception Notification]
: : ------------------------------------------------------------------------
: : Project Project1.exe raised exception class EStackOverflow with message
: : 'Stack overflow', Process stopped.
: : Use Step or Run to continue
: : [OK] [Help]
: : ------------------------------------------------------------------------
: :
: :
: : 제가 무엇을 잘못했는지...
: : 그리고 해결책은 무엇인지 알려주시면 감사하겠습니다.
: :
: : 고수님들 부탁드립니다.
|