TÌNHCác nhà xây dựng bản ghi Delphi có thực sự cần thiết không?
Tôi đang nghiên cứu "More Mã hóa trong Delphi" Nick Hodges, và ông đang sử dụng một kỷ lục TFraction
để giải thích điều hành quá tải. Tôi đã tự viết bản ghi này:
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;
Tất nhiên, tôi phải tạo một hàm tạo vì trong Q (lý trí) tôi phải có mẫu số không bằng 0.
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;
VẤN ĐỀ
Kể từ khi quá tải toán tử trả về một TFraction
, tôi sẽ xác định một hoạt động như thế này:
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;
Như bạn có thể thấy ở đây, tôi tạo một tmp
được trả về từ hàm.
Khi tôi đọc cuốn sách Marco Cantu, ông đã sử dụng cách tiếp cận khác:
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;
Tôi đã thực hiện một số xét nghiệm, và tôi thấy rằng cả hai cho tôi kết quả chính xác, nhưng có cái gì đó mà tôi không thể hiểu được. Trong phương pháp tiếp cận đầu tiên, tôi tuyên bố tmp và sau đó tôi gọi hàm tạo để tôi có thể trả lại TFraction
. Trong phương pháp thứ hai, tôi thay vì không tạo ra bất cứ điều gì vì các bản ghi có một hàm tạo tự động. Các tài liệu, trên thực tế, nói rằng:
Các bản ghi được tạo tự động, sử dụng một đối số mặc định không có đối số , nhưng các lớp phải được xây dựng một cách rõ ràng. Bởi vì các bản ghi có một hàm tạo không có đối số mặc định, bất kỳ người tạo nào được xác định bởi người dùng được định nghĩa thì phải có một hoặc nhiều tham số.
Ở đây tôi có một hàm tạo bản ghi do người dùng xác định. Vì vậy:
Gọi hàm tạo trên
tmp
cách tiếp cận đầu tiên không cần thiết? Nếu tôi muốn gọiReduce
(đó là một thủ tục), tôi cần phải tạo một biến. Có phảiResult
chỉ trả về một bản sao củatmp
mà không cần tạo bất kỳ thứ gì không?Trong phương pháp thứ hai, là
Result.aNumerator
vàResult.aDenominator
thông số của hàm tạo được tạo tự động?
Trên ghi chú không liên quan, thường là sử dụng 'F' làm tiền tố cho trường riêng tư trong một lớp và tiền tố' A' cho tham số phương pháp (bạn sử dụng). Ở Delphi, nó ổn, nhưng rõ ràng, ở Lazarus, điều đó sẽ không biên dịch được. –
Ok cảm ơn bạn tôi không biết, tôi đang sử dụng một tham số và các biến. Tôi sẽ thay đổi thói quen của mình! –
@Jerry Ý bạn là gì. FPC không thực thi các quy tắc quy ước đặt tên. –