Using C++Builder, I created a new project, added a DataModule to the project, added a reference to that DataModule in the MainForm. I ran it and closed the MainForm. Result – no problem.
Then, I added a destructor to the DataModule, recompiled, and it ran fine until I closed the MainForm, and then I got an Access Violation.
What does it take to be able to add a destructor to a DataModule?
Here is the code I came up with:
DataMod2.h
#ifndef DataMod2H
#define DataMod2H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
//---------------------------------------------------------------------------
class TDataModule2 : public TDataModule
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations
__fastcall TDataModule2(TComponent* Owner);
~TDataModule2();
};
//---------------------------------------------------------------------------
extern PACKAGE TDataModule2 *DataModule2;
//---------------------------------------------------------------------------
#endif
DataMod2.cpp
#pragma hdrstop
#include "DataMod2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma classgroup "FMX.Controls.TControl"
#pragma resource "*.dfm"
TDataModule2 *DataModule2;
//---------------------------------------------------------------------------
__fastcall TDataModule2::TDataModule2(TComponent* Owner)
: TDataModule(Owner)
{
}
//---------------------------------------------------------------------------
TDataModule2::~TDataModule2() {
}
Unit2.h
#ifndef Unit2H
#define Unit2H
#include "DataMod2.h"
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
TDataModule2 * dataMod;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit2.cpp
#include <fmx.h>
#pragma hdrstop
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
dataMod = new TDataModule2(Form1);
}
//---------------------------------------------------------------------------
Overriding the base class destructor requires matching the entire signature of the destructor, including the calling convention. The DataModule derives from TObject
, and TObject
's destructor looks like this:
__fastcall virtual ~TObject();
Your DataModule destructor is missing the __fastcall
calling convention:
class TDataModule2 : public TDataModule
{
...
__fastcall ~TDataModule2();
};
__fastcall TDataModule2::~TDataModule2() {
}
Also, in your TForm1
constructor, you should be using the this
pointer as the DataModule's Owner
rather than using the global Form1
variable:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
dataMod = new TDataModule2(this);
}