i have a base class declarated like this
type
TBaseClass=class
protected
constructor Create(LoadData:boolean;const Param1,Param2:string); overload;
public
Destructor Destroy; override;
end;
Now in another unit a child class TChid_Class
which descend from TBaseClass
TChid_Class=class(TBaseClass)
function Create(const Param1, Param2 : String;const Param3 : OleVariant ; var Param4 : LongInt): Integer;overload;
constructor Create; overload;
constructor Create(LoadData:boolean); overload;
end;
in this class exist a function called Create
like the constructors, the problem is , when i try to create a instance to the TChid_Class
i have an access violation.
i wrote this small console app which show the problem
program TestClass;
{$APPTYPE CONSOLE}
uses
Variants,
SysUtils;
type
TBaseClass=class
protected
constructor Create(LoadData:boolean;const Param1,Param2:string); overload;
public
Destructor Destroy; override;
end;
TChid_Class=class(TBaseClass)
function Create(const Param1, Param2 : String;const Param3 : OleVariant ; var Param4 : LongInt): Integer;overload;
constructor Create; overload;
constructor Create(LoadData:boolean); overload;
end;
{ TBaseClass }
constructor TBaseClass.Create(LoadData: boolean; const Param1, Param2: string);
begin
inherited Create;
Writeln('constructor TBaseClass.Create(LoadData: boolean; const Param1, Param2: string);');
end;
destructor TBaseClass.Destroy;
begin
//Code
inherited;
end;
{ TChid_Class }
function TChid_Class.Create(const Param1, Param2: String; const Param3: OleVariant; var Param4: Integer): Integer;
begin
Writeln('function create');
Result:=0;
end;
constructor TChid_Class.Create;
begin
Writeln('constructor TChid_Class.Create');
Create(True);
end;
constructor TChid_Class.Create(LoadData: boolean);
begin
Writeln('constructor TChid_Class.Create(LoadData: boolean)'); //here is the access violation
Create(LoadData,'Value 1','Value 2');
end;
var
Invoker : TChid_Class;
Pid : integer;
begin
try
Invoker:=TChid_Class.Create;
try
Invoker.Create('','',Unassigned,Pid)
finally
Invoker.Free;
end;
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
readln;
end.
if i rename the function create, the problem is go away, but i am looking for a solution without rename the create function or the constructors.
using delphi 2007
Thanks in advance.
With Delphi 7 I get an AV too. Renaming the method or moving it (as suggested by Sertac Akyuz) fixes the AV.
What I discovered by looking at the assembler:
When creating a new object a non-zero value is placed in register dl
before calling the constructor.
mov dl,$01 // dl set to 1
mov eax,[$00401268]
call TChild_Class.Create
Then in the constructor, on the begin
line, ClassCreate is called when dl
is non-zero.
test dl,dl
jz +$08 //if dl = 0 then do not call ClassCreate
add esp,-$10
call -$00000396 //calls ClassCreate
But then it goes wrong, with your code, the compiler sets dl
to 1 again before calling Create(True)
, so on the begin
line of TChid_Class.Create(LoadData: boolean);
, ClassCreate is called again which results in an AV.
After renaming your function or moving its declaration, the compiler clears dl
(xor edx,edx
) instead of setting it to 1, before calling Create(True)
.
My guess is that it is a bug in the Delphi compiler which is fixed in Delphi 2010 and higher.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With