Embarcadero RAD Studio XE7 컴파일러를 사용하여 C++ 프로젝트를 만들고 있습니다. 이 프로젝트에서 다음 코드 디자인이 : 소멸자를 포함 TForm 클래스, 상속,C++ - 파괴 순서 - 메인 클래스 소멸자보다 먼저 함수의 정적 멤버가 소멸됩니다.
- 기본 폼을
- 클래스 "foo는"
- 클래스 "바"어떤 클래스 "에 foo "정적 멤버입니다
이제 주 양식 소멸자에서 foo 클래스에 포함 된 함수를 실행해야합니다. 내 기본 폼의 소멸자에서 나는 다음과 같은 코드를 삽입 한 그래서 :
는__fastcall TForm1::~TForm1()
{
Bar::m_Foo.ExecuteSomething();
}
그러나 오류 (이 오류에 "라는 순수 가상 함수"내 경우에는이 시점에서 내 응용 프로그램의 충돌, 의존 물론입니다 내 구현, 난 여기에 세부 사항을 입력하지 않습니다). 사실, Bar :: m_Foo 클래스는 TForm1 소멸자보다 먼저 삭제되었습니다.
#ifndef AClassH
#define AClassH
#include <Windows.h>
class Foo
{
public:
Foo()
{
std::cout << "Foo constructor - CALLED" << std::endl;
}
virtual ~Foo()
{
std::cout << "Foo destructor - CALLED" << std::endl;
}
};
class Bar
{
private:
static Foo m_Foo;
};
#endif
Class.h
Main.h
#ifndef MainH
#define MainH
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
class TForm1 : public TForm
{
__published:
public:
__fastcall TForm1(TComponent* Owner);
virtual __fastcall ~TForm1();
private:
};
extern PACKAGE TForm1 *Form1;
#endif
하여 Main.cpp
#include <vcl.h>
#pragma hdrstop
#include "Main.h"
#include <iostream.h>
#pragma package(smart_init)
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
std::cout << "TForm1 constructor - CALLED" << std::endl;
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
std::cout << "TForm1 destructor - CALLED" << std::endl;
}
//---------------------------------------------------------------------------
:
문제를 간략하게 설명하기 위해, 나는 여기에 최소한의 코드 예제를 다시Class.cpp
#include "Class.h"
//---------------------------------------------------------------------------
Foo Bar::m_Foo;
//---------------------------------------------------------------------------
일단 실행은, 위의 코드는 다음과 같은 결과를 보여줍니다
Foo constructor - CALLED
TForm1 constructor - CALLED
Foo destructor - CALLED
TForm1 destructor - CALLED
따라서 푸 클래스의 사용을시키는 정적 멤버 소멸자가 전에 기본 폼의 소멸자 호출이 밑줄, 내 TForm1 소멸자에서 위험합니다. 이 결과는 응용 프로그램이 종료 될 때 정적 멤버 변수가 범위를 벗어난 것으로 항상 믿었 기 때문에 (예 : , 이후) 내 기본 폼 소멸자 호출이 신뢰할 수 없기 때문에 조금 혼란 스러웠습니다. 그러나 그것이 사실이 아닌 것처럼 보입니다. 그들이 범위를 벗어난 될 때
- 는 정적 멤버에 대한 규칙 무엇과 :
그래서 내 질문은?
- 내 Foo 소멸자가 주 양식 소멸자보다 먼저 호출되는 이유는 무엇입니까?
- 이 파괴 명령은 C++ 표준에 정의되어 있습니까? 아니면 RAD Studio 버그입니까?
- 소멸자 형태로 호출되는 함수는 필자의 경우 전역 GDI + 인스턴스를 해제하는 데 사용됩니다. 공용 컨텍스트 (주 EXE PLUS dll)에서 GDI +를 사용하면 주 양식 호출이 최종 잠금을 해제 할 수 있습니다. 이러한 이유로 정적 키워드가 중요합니다. 하지만 내가 뭔가 잘못하고있는거야? 어떤 디자인이 더 좋을까요?
------------------------- 편집 ------------------
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
USEFORM("Main.cpp", Form1);
//---------------------------------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
try
{
Application->Initialize();
Application->MainFormOnTaskBar = true;
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
여기서'Form1'은 어떻게 할당 되나요? 'TForm1'은 어떻게 생성되고 파괴됩니까? –
좋은 발언. 게시 됨, 감사합니다. –