СИТУАЦИЯДействительно ли нужны конструкторы записей Delphi?
Я изучаю «Больше Coding в Delphi» Ник Ходжес, и он использует TFraction
запись объяснить перегрузки операторов. Я написал сам этот рекорд:
type
TFraction = record
strict private
aNumerator: integer;
aDenominator: integer;
function GCD(a, b: integer): integer;
public
constructor Create(aNumerator: integer; aDenominator: integer);
procedure Reduce;
class operator Add(fraction1, fraction2: TFraction): TFraction;
class operator Subtract(fraction1, fraction2: TFraction): TFraction;
//... implicit, explicit, multiply...
property Numerator: integer read aNumerator;
property Denominator: integer read aDenominator;
end;
Конечно, я должен был создать конструктор, потому что в Q (рациональных чисел) я должен иметь знаменатель, который не равен нулю.
constructor TFraction.Create(aNumerator, aDenominator: integer);
begin
if (aDenominator = 0) then
begin
raise Exception.Create('Denominator cannot be zero in rationals!');
end;
if ((aNumerator < 0) or (aDenominator < 0)) then
begin
Self.aNumerator := -aNumerator;
Self.aDenominator := -aDenominator;
end
else
begin
Self.aNumerator := aNumerator;
Self.aDenominator := aDenominator;
end;
end;
ПРОБЛЕМА
Поскольку оператор перегрузки возвращает TFraction
, я собираюсь определить операцию, как это:
class operator TFraction.Add(fraction1, fraction2: TFraction): TFraction;
var
tmp: TFraction;
begin
//simple algorithm of the sum
tmp := TFraction.Create(fraction1.Numerator*fraction2.Denominator+fraction1.Denominator*fraction2.Numerator, fraction1.Denominator*fraction2.Denominator);
tmp.Reduce;
//return the result
Result := tmp;
end;
Как вы можете видеть здесь, я создавая tmp
, который возвращается из функции.
Когда я прочитал книгу Марко Канту, он использовал другой подход:
class operator TFraction.Add(fraction1, fraction2: TFraction): TFraction;
begin
Result.aNumerator := (fraction1.Numerator*fraction2.Denominator+fraction1.Denominator*fraction2.Numerator);
Result.aDenominator := fraction1.Denominator*fraction2.Denominator;
end;
Я сделал несколько тестов, и я вижу, что оба дают мне правильный результат, но есть что-то, что я не могу понять. В первом подходе я объявляю tmp, а затем я вызываю конструктор, чтобы я мог вернуть TFraction
. Во втором подходе я вместо этого ничего не создаю, потому что записи имеют автоматический конструктор. Документация, на самом деле, говорит, что:
отчетов построены автоматически, не используя по умолчанию без аргументов конструктора, но классы должны быть явно построены. Поскольку записи имеют конструктор без аргументов по умолчанию, любой пользовательский конструктор записи должен иметь один или несколько параметров.
Здесь у меня есть пользовательский конструктор записи. Итак:
ли вызов конструктора на
tmp
первого подхода не нужен? Если я хочу позвонитьReduce
(это процедура), мне нужно создать переменную. Является лиResult
просто возвращением копииtmp
без создания чего-либо?Во втором подходе есть
Result.aNumerator
иResult.aDenominator
параметры автоматического созданного конструктора?
на несвязанной ноте, это, как правило, нормальная практика, чтобы использовать 'f' как префикс для частных полей в классе, и префикс' Ā' для параметров методы (который вы используете). В Delphi это прекрасно, но, видимо, в Лазаре, это не скомпилировалось. –
Хорошо спасибо, я не знал, я использую параметры и переменные. Я изменю свою привычку! –
@Jerry Что вы имеете в виду. FPC не применяет правила правил именования. –