私は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
こうしてのFooクラスのいずれかの使用をさせる静的メンバデストラクタが前にメインフォームのデストラクタと呼ばれるこのアンダーライン、私のTForm1デストラクタで危険です。この結果は、アプリケーションが終了したときに静的メンバー変数が範囲外になったことを常に信頼していたため、私はちょっと困惑させました。つまり、AFTER私のメインフォームデストラクタの呼び出しです。しかし、それはそうではないようです。
だから私の質問は以下のとおりです。
- な静的メンバとするとき、彼らがスコープ外になる程度のルールは何ですか?
- 私のFooデストラクタがメインフォームデストラクタの前に呼び出されるのはなぜですか?
- この破棄命令はC++標準で定義されていますか、代わりにRAD Studioのバグですか?
- 私のケースでは、グローバルなGDI +インスタンスをリリースするために、フォームdestructorによって呼び出される関数が使用されています。 GDI +を共有コンテキスト(メインexe プラスDLL dll)で使用すると、メインフォーム呼び出しによって最終的なロックが解放されるかどうかが決まります。そのため、ここでは静的キーワードが重要です。しかし私は何か間違っているのですか?どのデザインが良いでしょうか?
------------------------- EDIT ------------------ ---------------ここ
もTForm1が作成され、削除されている上記の例のアプリメインエントリポイントのコードである:
#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'はどのように作成され破壊されましたか? –
良い発言。投稿、ありがとう –