1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
| program Project8;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TBaseClass = class;
TFields = class
private
fRefCount : integer;
fField2 : integer;
fField1 : integer;
public
property Field1 : integer read fField1 write fField1;
property Field2 : integer read fField2 write fField2;
property RefCount : integer read fRefCount;
procedure Assign(Src: TFields);
constructor Create; overload; virtual;
constructor Create(const aField1, aField2: integer); overload; virtual;
destructor Destroy; override;
end;
TBaseClass = class
private
fFields: TFields;
procedure SetFields(const Value: TFields);
protected
function GetTraitment: integer; virtual;
public
property Fields : TFields read fFields write SetFields;
property Traitment : integer read GetTraitment;
constructor Create(aFields: TFields); virtual;
destructor Destroy; override;
end;
TClassA = class(TBaseClass)
protected
function GetTraitment: integer; override;
end;
TClassB = class(TBaseClass)
protected
function GetTraitment: integer; override;
end;
{ TFields }
procedure TFields.Assign(Src: TFields);
begin
if assigned(Src) then
begin
fField1 := Src.fField1;
fField2 := Src.fField2;
end;
end;
constructor TFields.Create;
begin
fRefCount := 0;
fField1 := 0;
fField2 := 0;
end;
constructor TFields.Create(const aField1, aField2: integer);
begin
Create;
fField1 := aField1;
fField2 := aField2;
end;
destructor TFields.Destroy;
begin
assert(fRefCount = 0, 'Erreur : des objets références encore cette classe.');
inherited;
end;
{ TBaseClass }
constructor TBaseClass.Create(aFields: TFields);
begin
fFields := aFields;
assert(assigned(aFields), 'Erreur : aFields doit être assigné.');
inc(fFields.fRefCount);
end;
destructor TBaseClass.Destroy;
begin
if Assigned(fFields) then
dec(fFields.fRefCount);
inherited;
end;
function TBaseClass.GetTraitment: integer;
begin
assert(Assigned(fFields), 'Erreur : champs non assignés!');
result := 0;
end;
procedure TBaseClass.SetFields(const Value: TFields);
begin
fFields.Assign(Value);
end;
{ TClassA }
function TClassA.GetTraitment: integer;
begin
inherited;
result := fFields.Field1 + fFields.Field2;
end;
{ TClassB }
function TClassB.GetTraitment: integer;
begin
inherited;
result := fFields.Field1 - fFields.Field2;
end;
var
Fields : TFields;
CA, CB : TBaseClass;
begin
Fields := TFields.Create(10, 10);
CA := TClassA.Create(Fields);
CB := TClassB.Create(Fields);
try
CA.Fields.Field1 := 20;
CB.Fields.Field2 := 30;
writeLn('Reference count : ', Fields.RefCount);
writeLn('Field 1 value : ', Fields.Field1);
writeLn('Field 2 value : ', Fields.Field2);
writeLn;
writeLn('Class A result : ', CA.Traitment);
writeLn('Class B result : ', CB.Traitment);
writeLn;
readLn;
finally
CB.Free;
CA.Free;
Fields.Free;
end;
end. |
Partager