【发布时间】:2017-07-18 20:58:18
【问题描述】:
确实,网上有很多关于这个的东西,但我读的越多,我就越困惑。我编写了一个名为Combinatorics 的组件,它可以处理一些数学概率问题。代码非常简短易懂,因为我不想让它变得复杂。我在这里做一个小预览:
//Combinatorio.pas
type
ICombinatorio = interface
function getSoluzioni(): integer; //soluzioni means "Solutions"
function getFormula(): string;
end;
//ImplCombinatorio.pas
type
TCombinazioni = class(TInterfacedObject, ICombinatorio)
private
n, k: integer;
ripetizione: boolean;
function fattoriale(const x: integer): integer;
public
constructor Create(const n, k: integer; const ripetizione: boolean);
function getSoluzioni(): integer;
function getFormula(): string;
end;
TDisposizioni = class(TInterfacedObject, ICombinatorio)
private
n, k: integer;
ripetizione: boolean;
function fattoriale(const x: integer): integer;
public
constructor Create(const n, k: integer; const ripetizione: boolean);
function getSoluzioni(): integer;
function getFormula(): string;
end;
TPermutazioni = class(TInterfacedObject, ICombinatorio)
private
n: integer;
k: string;
ripetizione: boolean;
function fattoriale(const x: integer): integer;
public
constructor Create(const n: integer; const k: string; ripetizione: boolean);
function getSoluzioni(): integer;
function getFormula(): string;
end;
你不需要看函数和过程是如何实现的,这对问题并不重要(你可以很容易地想象它们做了什么)。
这是我的第一个组件,我已经编译并安装了它,它可以工作。但是我有些看不懂。
unit TCombinatorio;
interface
uses
System.SysUtils, System.Classes, Combinatorio, ImplCombinatorio;
type
cCombinatorio = (cNull = 0, cDisposition = 1, cPermutation = 2, cCombination = 3);
type
TCombinatorics = class(TComponent)
strict private
{ Private declarations }
Fn, Fk: integer;
FRep: boolean;
FType: cCombinatorio;
FEngine: ICombinatorio;
procedure Update;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
function getSolution: integer;
function getFormula: string;
published
property n: integer read Fn write Fn;
property k: integer read Fk write Fk;
property kind: cCombinatorio read FType write FType default cNull;
property repetitions: boolean read FRep write FRep;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('RaffaeleComponents', [TCombinatorics]);
end;
{ TCombinatorics }
constructor TCombinatorics.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Fn := 0;
Fk := 0;
FType := cNull;
repetitions := false;
end;
function TCombinatorics.getFormula: string;
begin
Update;
Result := FEngine.getFormula;
end;
function TCombinatorics.getSolution: integer;
begin
Update;
Result := FEngine.getSoluzioni;
end;
procedure TCombinatorics.Update;
begin
case FType of
cDisposition:
FEngine := TDisposizioni.Create(n, k, repetitions);
cPermutation:
FEngine := TPermutazioni.Create(n, '', repetitions);
cCombination:
FEngine := TCombinazioni.Create(n, k, repetitions);
cNull:
raise Exception.Create('You have to select a type.');
end;
end;
end.
查看Update; 过程。我之所以创建它是因为当用户以表单形式删除组件 (link) 时,他必须在对象检查器中(或在某处使用代码)设置构造函数中所需的 3 个重要参数。
由于FEngine: ICombinatorio 我可以为它分配一个类(TCombinazioni、TDisposizioni 或 TPermutazioni)而无需最后尝试,因为存在引用计数机制。我不确定我是否正确编码。假设:
- 用户选择
cDisposition并进行计算 - 用户选择
cDisposition(不同的值)并进行计算 - 用户选择
cPermutation并进行计算
我一直在处理FEngine。参考计数如何变为零?当表单(和组件)破坏时它会归零吗?我希望我能很好地解释我不明白的地方。 FEngine 是一个私有变量,我在运行时分配给它不同的类(调用 Create)。当表单销毁或分配新类时,引用计数是否变为 0?
我像上面那样编码,因为 nick hodges 在他的书中做到了这一点,我当然相信他,但我想知道我是做什么的。
【问题讨论】:
-
您可以简单地将析构函数添加到您的接口对象并放置断点以找出发生了什么。
-
我猜你指的是“delphi中编码”的TEncryption示例;)我刚刚检查了这本书,当他谈到时,你应该在章节中间找到你的问题的答案TInterfacedObject!
-
@Sertac 我不知道你在说什么对不起,我现在正在学习,所以我觉得问起来更容易
-
@Alberto 是那本书的第 2 章 :) 是的,他解释得很好,但我不太确定我从这一章中得到了什么
-
@Raffaele 好的。如果您想了解更多信息,您可以立即尝试。将析构函数放入您的接口对象(TCombinazioni,...)。他们只需拨打
inherited即可。然后在“继承”语句上放置断点。然后在“编译”项目选项中选择“使用调试dcus”。并运行项目。当调试器停止时检查调用堆栈。
标签: delphi