按照Eric Harmon 的说法,如下所示
IFormattedNumber = interface
['{86EF89E2-347C-480F-9A6C-1E57F134E58E}']
function FormatttedString: string;
procedure SetValue(AValue: Integer);
end;
TFormattedInteger = class(TObject, IFormattedNumber)
private
FRefCount: Integer;
FValue: Integer;
public
constructor Create(aValue: Integer);
function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
function FormatttedString: string;
procedure SetValue(AValue: Integer);
end;
procedure DoSomethingWithInterface(Intf: IFormattedNumber);
implementation
procedure DoSomethingWithInterface(Intf: IFormattedNumber);
begin
ShowMessage(Intf.FormatttedString);
end;
procedure CreateAndUseObject;
var
MyInteger: TFormattedInteger;
begin
MyInteger := TFormattedInteger.Create(12);
DoSomethingWithInterface(MyInteger as IFormattedNumber);
MyInteger.SetValue(10);
end;
{ TFormattedInteger }
constructor TFormattedInteger.Create(aValue: Integer);
begin
inherited Create;
FValue := aValue;
end;
function TFormattedInteger.FormatttedString: string;
begin
Result := 'The Value is ' + IntToStr(FValue)
end;
function TFormattedInteger._AddRef: Integer;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TFormattedInteger._Release: Integer;
begin
Dec(FRefCount);
Result := FRefCount;
if FRefCount = 0 then
Destroy;
end;
function TFormattedInteger.QueryInterface(const IID: TGUID;
out Obj): HRESULT;
const
E_NOINTERFACE = $80004002;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
procedure TFormattedInteger.SetValue(AValue: Integer);
begin
FValue := AValue;
end;
结果是编译也通不过:
[Error] Unit1.pas(52): Operator not applicable to this operand type
这句有问题了:
DoSomethingWithInterface(MyInteger as IFormattedNumber);
当然这样是没有问题的:DoSomethingWithInterface(MyInteger as IFormattedNumber);
真奇怪,本来是来验证as 对 引用计数的影响的,结果进行不下去了。