Delphi 2006 представил новые возможности для записей, делая их более объектно-ориентированными.
В каких ситуациях тип записи более подходит для дизайна, чем тип класса? Какое преимущество имеет использование этих типов записей?
Delphi 2006 представил новые возможности для записей, делая их более объектно-ориентированными.
В каких ситуациях тип записи более подходит для дизайна, чем тип класса? Какое преимущество имеет использование этих типов записей?
У вас есть записи, объекты и классы.
Записи доступны с турбо-паскалем 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 | - |
------------------|-----------------------------|
Я думаю, что эти функции были также доступны в Delphi 8 и 2005.
Главное руководство: если вы сомневаетесь, используйте класс.
В остальном вам нужно понять основное различие: объекты класса всегда используются через ссылку и создаются путем вызова конструктора.
Управление памятью и распределение для записей такие же, как и для базовых типов (т.е. целое, двойное). Это означает, что они передаются методам по значению (если не используется var). Также вам не нужны бесплатные записи и причина, по которой они поддерживают перегрузку оператора. Но нет наследования или виртуальных методов и т.д. Новые записи могут иметь конструктор, но он используется как необязательный.
Основные области и критерии использования записей:
при работе с структурами из Win32 API
когда типы не имеют идентификатора (потому что назначение означает копирование)
когда экземпляры не слишком велики (копирование больших записей становится дорогим)
при построении типов значений, поведение которых должно имитировать числовые типы. Примерами являются DateTime, Сложные числа, Векторы и т.д. И тогда перегрузка оператора является приятной функцией, но не делает этого решающим фактором.
И по эффективности, не переусердствуйте:
И, наконец, правила использования класса или записей на самом деле не изменились из более ранних версий Delphi.
В дополнение к другим ответам (перегрузка операторов, облегченные типы значений), рекомендуется сделать ваши записи счетчиков вместо классов. Поскольку они выделены в стеке, нет необходимости создавать и уничтожать их, что также устраняет необходимость скрытого try..finally блокировать, что компилятор размещает вокруг перечислений типа класса.
Подробнее см. http://hallvards.blogspot.com/2007/10/more-fun-with-enumerators.html.
Вы можете использовать перегрузку оператора (например, неявные преобразования). Это можно сделать и на Delphi 2007+ или 2006.NET на объектах, но только на этих записях в 2006 win32.