Sal*_*dor 5 delphi delphi-2007
我有这样的基类声明
type
TBaseClass=class
protected
constructor Create(LoadData:boolean;const Param1,Param2:string); overload;
public
Destructor Destroy; override;
end;
Run Code Online (Sandbox Code Playgroud)
现在,在另一个单元的子类TChid_Class,从下降 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;
Run Code Online (Sandbox Code Playgroud)
在此类中,存在一个称为Create构造函数的函数,问题是,当我尝试创建实例时TChid_Class遇到访问冲突。
我写了这个小控制台应用程序,显示了问题
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.
Run Code Online (Sandbox Code Playgroud)
如果我将函数重命名为create,问题就消失了,但是我正在寻找一种解决方案,而无需重命名create函数或构造函数。
使用Delphi 2007
提前致谢。
有了 Delphi 7,我也得到了 AV。重命名该方法或移动它(按照 Sertac Akyuz 的建议)可以修复 AV。
我通过查看汇编器发现了什么:
dl创建新对象时,在调用构造函数之前会在寄存器中放置一个非零值。
mov dl,$01 // dl set to 1
mov eax,[$00401268]
call TChild_Class.Create
Run Code Online (Sandbox Code Playgroud)
然后在构造函数中,当is 非零begin时,就调用 ClassCreate 。dl
test dl,dl
jz +$08 //if dl = 0 then do not call ClassCreate
add esp,-$10
call -$00000396 //calls ClassCreate
Run Code Online (Sandbox Code Playgroud)
但随后就出错了,在你的代码中,编译器dl在调用 之前再次设置为 1 Create(True),因此在begin行上TChid_Class.Create(LoadData: boolean);,再次调用 ClassCreate ,这会产生 AV。
重命名函数或移动其声明后,编译器会在调用 之前清除dl( xor edx,edx) 而不是将其设置为 1 Create(True)。
我的猜测是,这是 Delphi 编译器中的一个错误,已在 Delphi 2010 及更高版本中修复。
| 归档时间: |
|
| 查看次数: |
577 次 |
| 最近记录: |