5

これは、私のプログラムが使用するクラス階層です。

ここに画像の説明を入力

TForm_Upgrade_Database のコンストラクタは次のようになります。

__fastcall TForm_Upgrade_Database::TForm_Upgrade_Database(TComponent* Owner, int newest_version) : TForm(Owner) { }

Formular のインスタンスを作成しようとした後

TForm_Upgrade_Database *dlg = new TForm_Upgrade_Database(this, newest_version);

私のプログラムは EStackOverflow 例外をスローします

ここに画像の説明を入力

プログラムを停止し、TForm_Upgrade_Database コンストラクターのブレークポイントで再度実行しました。いくつかのステップの後、コールスタックは次のようになります。

ここに画像の説明を入力

TCustomForm コンストラクターがその子孫のコンストラクターを呼び出そうとするのはどうしてですか?

最小限のテスト ケース:

so_project.cpp:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "f_form.h"
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
   TForm_Upgrade_Database *form = new TForm_Upgrade_Database(NULL, 10);
   delete form;
   form = NULL; 

   return 0;
}
//---------------------------------------------------------------------------

f_form.cpp:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "f_form.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm_Upgrade_Database *Form1;
//---------------------------------------------------------------------------
__fastcall TForm_Upgrade_Database::TForm_Upgrade_Database(TComponent* Owner, int x)
   : TForm(Owner)
{
}
//---------------------------------------------------------------------------

f_form.h:

//---------------------------------------------------------------------------

#ifndef f_formH
#define f_formH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm_Upgrade_Database : public TForm
{
__published:    // IDE-managed Components
private:    // User declarations
public:     // User declarations
   __fastcall TForm_Upgrade_Database(TComponent* Owner, int x);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm_Upgrade_Database *Form1;
//---------------------------------------------------------------------------
#endif
4

2 に答える 2

4

TFormTComponent*intパラメーターをこの順序で受け取る仮想コンストラクターがあります。そのコンストラクターをオーバーライドしています。パラメーターのみを受け取る基本クラスのコンストラクターを呼び出すと、TComponent*実際には、これらのコンストラクターが内部で相互に呼び出し合うときに再帰ループが作成されます。

解決策は、真実を求める人が言ったことです。基本クラスのコンストラクターをオーバーライドしないように、派生コンストラクターのパラメーターを変更する必要がありますTComponent*/int。パラメータの順序を変更するだけで十分ですがint、別のデータ型に変更することもできます。

于 2012-03-20T22:05:39.033 に答える
1

これは、デルファイ ライブラリの非標準ソリューションに関係していると思います。VCL ライブラリは、Delphi Pascal で作成およびコンパイルされます。C++ との連携は、インターフェース ファイル (拡張子 *.hpp) を介して行われます。コンパイルされたバイナリ コードが、不正なメモリ オフセットでコンストラクタ パラメータを検索している可能性があります。したがって、これはおそらく呼び出し規約の問題です。

コンストラクターでパラメーターを変更すると、新しいパラメーターが最初になるようにフォーミュラーのインスタンスを作成することに成功しました。

f_form.h:

__fastcall TForm_Upgrade_Database(int x, TComponent* Owner);

f_form.cpp:

__fastcall TForm_Upgrade_Database::TForm_Upgrade_Database(int x, TComponent* Owner)
    : TForm(Owner)
{
}

so_project.cpp:

TForm_Upgrade_Database *form = new TForm_Upgrade_Database(10, NULL);
于 2012-03-20T08:08:22.487 に答える