Название статьи: Использование 'Inherited' в конструкторах записей (record) в современном Delphi
В последних версиях среды разработки Delphi от компании Embarcadero была добавлена возможность определения конструкторов для типов данных, известных как записи (records). Это нововведение позволяет использовать записи более гибко, предоставляя возможность инициализации полей при создании экземпляра. Однако возник вопрос: необходимо ли добавлять ключевое слово inherited в конструкторы записей? Давайте разберёмся.
Описание проблемы
В коде ниже представлен пример конструктора для записи TKMRect:
{ TKMRect }
constructor TKMRect.Create(aPoint: TKMPoint);
begin
inherited; // <<- Нужно ли добавлять эту строку?
Left := aPoint.X;
Top := aPoint.Y;
Right := aPoint.X;
Bottom := aPoint.Y;
end;
Вопрос разработчика заключается в следующем: нужно ли включать в конструктор записей ключевое слово inherited, и почему?
Альтернативный ответ
Рассмотрим код:
{ TKMRect }
constructor TKMRect.Create(aPoint: TKMPoint);
begin
inherited; // <<- Нужно ли добавлять эту строку?
Left := aPoint.X;
Top := aPoint.Y;
Right := aPoint.X + Width; // Исправление логической ошибки
Bottom := aPoint.Y + Height; // Исправление логической ошибки
end;
В данном случае виден явный баг в коде: поля Right и Bottom инициализируются значением X и Y соответственно, что неверно. Правильно было бы использовать значения X + Width и Y + Height, так как Right и Bottom обычно представляют собой правую границу и нижний край прямоугольника относительно его левого верхнего угла.
Подтвержденный ответ
Нет, добавлять строку inherited в конструкторы записей не требуется. Это связано с тем, что записи в Delphi не поддерживают наследование, и поэтому директива inherited в данном контексте является бесполезной (no-op). Рекомендуется использовать статические функции класса, например New, для создания новых значений, чтобы различать их от типов ссылочного типа. Это упрощает чтение и понимание кода на месте вызова.
Примеры использования
type
TKMRect = record
Left, Top: Integer;
Width, Height: Integer;
constructor Create(aLeft, aTop, aWidth, aHeight: Integer);
end;
constructor TKMRect.Create(aLeft, aTop, aWidth, aHeight: Integer);
begin
Left := aLeft;
Top := aTop;
Width := aWidth;
Height := aHeight;
end;
// Использование статической функции для создания экземпляра записи
var
MyRect: TKMRect;
begin
MyRect := TKMRect.Create(10, 20, 30, 40);
end;
Вывод
Использование конструкторов в записях может быть полезным для инициализации полей при создании экземпляра. Однако, важно помнить, что записи не поддерживают наследование, и ключевое слово inherited здесь лишнее. Рекомендуется использовать статические функции с понятными именами для создания новых значений записей.
Заключение
Разработчики использующие Delphi часто сталкиваются с заблуждением о необходимости использования директивы Inherited в конструкторах записей. Однако, согласно подтвержденным ответам экспертов, это не требуется из-за особенности архитектуры типов данных в Delphi. Вместо этого стоит использовать альтернативные способы создания новых экземпляров, например статические методы, что может быть полезно для повышения читабельности и предсказуемости кода.
В статье рассматривается вопрос необходимости использования ключевого слова `inherited` в конструкторах записей (record) в современном Delphi, а также даются примеры правильного и неправильного кода.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.