Лекс Айрин писал(а):Я не знаю, зачем нужен был вообще тип TObject, но тому кто это придумал но путаницы это прибавило знатно.
В чём разница написано в документации
http://docwiki.embarcadero.com/RADStudi ... ts_(Delphi)
А вот для чего изобрели - тоже можно понять. Дело в том, что object располагается на стеке, если хочется разместить его в динамической памяти - то нужно будет ухитряться (для этого есть специальная форма процедуры New). Можно посмотреть обсуждение:
http://www.programmersforum.ru/showthread.php?t=203940Там veniside более-менее внятно описал, в чём разница между object и class. Считается, что object - deprecated и его использование нежелательно, но это только потому что Borland переместила все фенечки object (например, методы) в record и радуется этому.
Базовые отличия:
- у всех class есть общий предок - TObject. У object общего предка по умолчанию нет, хотите - пишите руками.
- у всех class есть VMT и DMT, потому что их общий предок TObject имеет виртуальные методы (например, NewInstance, FreeInstance, Destroy). У object этого нет.
- все class помещаются в динамической памяти, object - это сами данные, при желании, их можно разместить в стеке, а можно - в динамической памяти. Кстати, придумав простенький object:
- Код: Выделить всё
TMan=object
strict private
fName:string;
fBirth:TDateTime;
function GetAge:integer;
public
property Name:string read fName;
property Age:integer read GetAge;
Constructor Init(const aName:string;Bd:TDateTime);
Destructor Clear;
function Full:string;virtual;
end;
и поиграв с sizeof(TMan) можно убедиться, что если у метода Full убрать virtual - то объект станет на 4 байта меньше, что говорит о том, что VMT у него компилятор убрал за ненадобностью.
- все class обязаны создаваться конструктором, иначе - AV, или ещё какие гадости, при выделении памяти, она автоматически инициализируется нулями (если InitInstance не перекрыт, но я в жизни такого не встречал). object теоретически можно не создавать, потому что если он лежит на стеке, то память под него выделена. Тем не менее, значения полей у object будут случайными, а потому, лучше всё-таки его инициализировать. Лежащий на стеке object удаляет сам компилятор, заботиться об этом не нужно и это очень удобно. К сожалению, освобождается только память object, никаких деструкторов не вызывается, а это было бы так здорово...
- class может наследоваться только от class, object - только от object, никакое перекрёстное опыление между ними невозможно!
- у object не бывает published секции. То есть RTTI для него не генерируется.
Таким образом, object - это ООП "для нищих", а поскольку мы все уже "богатые" (с точки зрения памяти), то все и пользуемся class.
Примечание: в одном из своих проектов я столкнулся с жутким своппингом, выедал я порядка 400 Мб памяти, на машине было только два гигабайта, причём гигабайт был отожран всякими сервисами тапа антивируса, так что на всё про всё было всего один гигабайт. В связи с тем, что я парсил огромные файлы PCad (мегабайт по двадцать) и строил на базе прочитанного дерево, я решил, что можно сэкономить на памяти, если перейти с class на object. Был разработан менеджер object, чтобы можно было комфортно (с enumerator, чтобы перечисление со встроенным фильтром и прочими плюшками) и в итоге за несколько дней новая версия заработала. Удалось сэкономить на всё про всё около 5% используемой памяти. Своппинг по прежнему был жутким. Проблема полностью исчерпалась, когда на рабочее место поставили машину с 64-битной операционкой и 8 Гб памяти. Вместо полутора-двух минут та же программа без дополнительных доработок стала работать за 9 секунд!
Мораль сей басни такова: ставьте более мощное железо и да пребудет с вами Сила. Не пытайтесь на крохах экономить.