在学<<Delphi Com编程>>中遇到的一个问题 ( 积分: 100 )

  • 主题发起人 主题发起人 iforward
  • 开始时间 开始时间
I

iforward

Unregistered / Unconfirmed
GUEST, unregistred user!
unit IntfUnit;

interface

uses
Classes, SysUtils, Dialogs;

type
IFormattedNumber = interface
['{2DE825C1-EADF-11D2-B39F-0040F67455FE}']
function FormattedString: string;
function GetName: string;
end;

TFormattedInteger = class(TInterfacedObject, IFormattedNumber)
private
FValue: Integer;
public
constructor Create(AValue: Integer);
destructor Destroy
override;
function FormattedString: string;
function GetName: string;
end;

TFormattedHexInteger = class(TFormattedInteger, IFormattedNumber)
public
destructor Destroy
override;
function FormattedString: string;
function GetName: string;
end;

implementation

uses
MainForm;

{ TFormattedInteger }

constructor TFormattedInteger.Create(AValue: Integer);
begin
inherited Create;

FValue := AValue;
end;

destructor TFormattedInteger.Destroy;
begin
Form1.Memo1.Lines.Add('TFormattedInteger.Destroy');

inherited Destroy;
end;

function TFormattedInteger.FormattedString: string;
begin
Result := 'The integer is ' + IntToStr(FValue);
end;

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

{ TFormattedHexInteger }

destructor TFormattedHexInteger.Destroy;
begin
Form1.Memo1.Lines.Add('TFormattedHexInteger.Destroy');

inherited Destroy;
end;

function TFormattedHexInteger.FormattedString: string;
begin
Result := 'The hex integer is $' + IntToHex(FValue, 4);
end;

function TFormattedHexInteger.GetName: string;
begin
Result := 'TFormattedHexInteger.GetName';
end;

end.

//////////////////////////////////////////////////////////
下面是我在窗体单元中的使用
procedure TForm1.Button1Click(Sender: TObject);
var
MyObject:Tobject;
MyNumber:IFormattedNumber;
begin
MyObject:=TFormattedInteger.Create(2);
MyNumber:=MyObject as IFormattedNumber
//此处编译器提示有错误,我是按书上来写的,为什么啊
ShowMessage(MyNumber.FormattedString);
end;

谢谢!
 
IFormattedNumber = interface
['{2DE825C1-EADF-11D2-B39F-0040F67455FE}']
这个接口的GUIDI不能照搬书上的
按ctrl+shift+G生成
 
MyObject:Tobject-- > MyObject: TFormattedInteger;
 
var
MyObject:Tobject;
这个声明错了,TObject没有实现IInterface接口,所以你得改成
var
MyObject:TInterfacedObject;
 
变量申明为接口类型,创建时使用实现了接口的类来创建即可.
 
你可以这样来使用一个接口
procedure TForm1.Button1Click(Sender: TObject);
var
MyNumber:IFormattedNumber;
begin
MyNumber := TFormattedInteger.Create(2);
//MyNumber := TFormattedHexInteger.Create(2);
ShowMessage(MyNumber.FormattedString);
MyNumber := nil
//销毁一个接口
end;
 
MyObject:Tobject-- > MyObject: TFormattedInteger

确实是这里的错误
但是我又发现了一个问题了
procedure TForm1.ShowName(Intf: IFormattedNumber);
begin
Memo1.Lines.Add(Intf.GetName);
end;

procedure TForm1.btnFunctionClick(Sender: TObject);
var
MyInt: TFormattedInteger;
MyHexIntf: IFormattedNumber;
begin
MyInt := TFormattedInteger.Create(27);
ShowName(MyInt);
// MyInteger is automatically destroyed here

// MyInt.Free
This will cause an access violation!
//书上说这里已经开始Free了,Memo1显示结果也是这样
MyInt.SetValue(10)
//这句很奇怪 MyInt已经destroy掉了 这里却还能调用其方法设置私有成员变量,为什么?
MyHexIntf := TFormattedHexInteger.Create(2047);
ShowName(MyHexIntf);


Memo1.Lines.Add('End of Procedure');
Memo1.Lines.Add('');

end;
///////////////////////////
下面是Memo1显示结果
TFormattedInteger.GetName
TFormattedInteger.Destroy
TFormattedHexInteger.GetName
End of Procedure

TFormattedHexInteger.Destroy
TFormattedInteger.Destroy
从结果可知MyInt确实是在上面的注释那儿Destroy
可是奇怪是既然Destroy,为什么还能SetValue呢?

再次谢谢各位
 
procedure TForm1.Button2Click(Sender: TObject);
var
MyObject:Tobject;
MyNumber:IFormattedNumber;
begin
MyObject:=TFormattedInteger.Create(2);
MyNumber:= TFormattedInteger( MyObject) as IFormattedNumber;
ShowMessage(MyNumber.FormattedString);
end;

這裡這樣寫就能通過了。我也看了那本書,我估計時當時的 Delphi 版本能通過
 
還有一個方法:

const
GUID_Test :TGUID = '{2DE825C1-EADF-11D2-B39F-0040F67455FE}';
var
MyObject:Tobject;
MyNumber:IFormattedNumber;
begin
MyObject:=TFormattedInteger.Create(200);
MyObject.GetInterface(GUID_Test, MyNumber);
if MyNumber <> nil then
ShowMessage(MyNumber.FormattedString);
 

Similar threads

后退
顶部