Когда следует использовать расширенные типы записей в Delphi вместо классов?
Delphi 2006 представил новые возможности для записей, делая их более объектно-ориентированными.
В каких ситуациях тип записи более подходит для дизайна, чем тип класса?
Какое преимущество имеет использование этих типов записей?
Ответы
Ответ 1
У вас есть записи, объекты и классы.
Записи доступны с турбо-паскалем 1. Они легкие, способные иметь свойства и методы, но не поддерживают наследование. Есть некоторые проблемы с функциями, которые возвращают записи. Если эти записи имеют методы, это иногда приводит к внутренним ошибкам:
type
TRec = record
function Method1: Integer;
end;
function Func: TRec;
procedure Test;
var
x : TRec;
begin
Func.Method1; // Sometimes crashes the compiler
// Circumvention:
x := Func;
x.Method1; // Works
end;
Объекты вводятся с turbo pascal 5, если я прав. Затем они предоставили путь для OO с паскалем. Они более или менее устарели с введением Delphi, но вы все равно можете их использовать. Объекты могут реализовывать интерфейсы.
Классы вводятся с Delphi 1 и наиболее универсальными. Они реализуют интерфейсы и поддерживают наследование. Но каждая переменная класса является скрытым указателем. Это означает, что классы должны создаваться в куче. К счастью, этот процесс в основном скрыт.
Ниже приведена таблица с различиями между тремя. Я добавил интерфейс для завершения.
|Class|Object|Record|Interface|
------------------|-----------------------------|
Are pointers? | y | n | n | y |
Inheritance | y | y | n | y |
Helpers | y | n | y | n |
Impl. Interface | y | y | n | - |
Visibility | y | y | n | n |
Method | y | y | y | y |
Fields | y | y | y | n |
Properties | y | y | y | y |
Consts | y | y | y | n |
Types | y | y | y | n |
Variants | n | n | y | n |
Virtual | y | n | y | - |
------------------|-----------------------------|
Ответ 2
Я думаю, что эти функции были также доступны в Delphi 8 и 2005.
Главное руководство: если вы сомневаетесь, используйте класс.
В остальном вам нужно понять основное различие: объекты класса всегда используются через ссылку и создаются путем вызова конструктора.
Управление памятью и распределение для записей такие же, как и для базовых типов (т.е. целое, двойное). Это означает, что они передаются методам по значению (если не используется var). Также вам не нужны бесплатные записи и причина, по которой они поддерживают перегрузку оператора. Но нет наследования или виртуальных методов и т.д. Новые записи могут иметь конструктор, но он используется как необязательный.
Основные области и критерии использования записей:
-
при работе с структурами из Win32 API
-
когда типы не имеют идентификатора (потому что назначение означает копирование)
-
когда экземпляры не слишком велики (копирование больших записей становится дорогим)
-
при построении типов значений, поведение которых должно имитировать числовые типы. Примерами являются DateTime, Сложные числа, Векторы и т.д. И тогда перегрузка оператора является приятной функцией, но не делает этого решающим фактором.
И по эффективности, не переусердствуйте:
- для небольших типов, которые вы часто помещаете в массивы.
И, наконец, правила использования класса или записей на самом деле не изменились из более ранних версий Delphi.
Ответ 3
В дополнение к другим ответам (перегрузка операторов, облегченные типы значений), рекомендуется сделать ваши записи счетчиков вместо классов. Поскольку они выделены в стеке, нет необходимости создавать и уничтожать их, что также устраняет необходимость скрытого try..finally блокировать, что компилятор размещает вокруг перечислений типа класса.
Подробнее см. http://hallvards.blogspot.com/2007/10/more-fun-with-enumerators.html.
Ответ 4
Вы можете использовать перегрузку оператора (например, неявные преобразования). Это можно сделать и на Delphi 2007+ или 2006.NET на объектах, но только на этих записях в 2006 win32.