请大家讨论一下:接口显式转换和隐式转换的不同(20分)

  • 主题发起人 主题发起人 gywlily
  • 开始时间 开始时间
G

gywlily

Unregistered / Unconfirmed
GUEST, unregistred user!
以下是测试程序的片段:
type
IFormattedNumber = interface
['{9C790B0D-176C-4B31-B0B6-969593DCA319}']
function GetName: string;
end;

TFormattedInteger = class(TInterfacedObject, IFormattedNumber)
public
Constructor Create;
protected
Function GetName: string;
end;

TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure ShowName(Intf: IFormattedNumber);
public
{ Public declarations }
end;

{ TForm1 }

procedure TForm1.ShowName(Intf: IFormattedNumber);
begin
Memo1.Lines.Add(Intf.GetName)
end;

procedure TForm1.Button1Click(Sender: TObject);
var
MyInt: TFormattedInteger;
begin
MyInt := TFormattedInteger.Create;
ShowName(MyInt as IFormattedNumber); // ShowName(MyInt);
MyInt.Free;
end;

{ TFormattedInteger }

constructor TFormattedInteger.Create;
begin
inherited ;
end;

function TFormattedInteger.GetName: string;
begin
Result := 'TFormattedNumber.GetName';
end;

结果:程序第一次执行到Button1Click的MyInt.Free;时抛出异常。
但是如果把Button1Click中的ShowName(MyInt as IFormattedNumber)改为注后的 语句// ShowName(MyInt);时第一次执行Button1Click没问题,第二次执行Button1Click时抛出异常:著名的"Access Violation"
愚人之问:使用ShowName(MyInt as IFormattedNumber), 函数返回时MyInt已经free掉了,接口也Release了,但为何隐式接口转换(ShowName(MyInt))得等到第二次执行Button1Click时才产生异常??
请大家讨论

 
TFormattedInteger是继承tinterfacedObject的, 对 tinterfacedObject, 你不需要用free方法去释放他, 只需将reference 指针置为nil就可以了. interface对象会在它的referenceCount为零时自动释放的.

var
MyInt: TFormattedInteger;
begin
MyInt := TFormattedInteger.Create;
ShowName(MyInt as IFormattedNumber); // ShowName(MyInt);
MyInt:= nil;
 
我是想就这到题目问一下接口显式转换和隐式转换在接口在函数参数中传递时有什么不同?
 
当你用MyInt as IFormattedNumber时, delphi会用QueryInterface去做一次type checking.
IFormattedNumber(MyInt)不做 type checking.

 
接受答案了.
 
后退
顶部