Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.11.2011, 10:08   #1
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию Отличие type T = Object от type T = Class?

В чем заключается отличие type T = Object от type T = Class?
Warn вне форума Ответить с цитированием
Старый 04.11.2011, 11:47   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
As an alternative to class types, you can declare object types using the syntax

type objectTypeName = object (ancestorObjectType)

memberList
end;

where objectTypeName is any valid identifier, (ancestorObjectType) is optional, and memberList declares fields, methods, and properties. If (ancestorObjectType) is omitted, then the new type has no ancestor. Object types cannot have published members.
Since object types do not descend from TObject, they provide no built-in constructors, destructors, or other methods. You can create instances of an object type using the New procedure and destroy them with the Dispose procedure, or you can simply declare variables of an object type, just as you would with records.

Object types are supported for backward compatibility only. Their use is not recommended.
в справке же все есть.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 04.11.2011, 12:18   #3
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

спасибо, но интересно где эта справка? у меня выводиться сообщение об ошибке если, если я выделю ключевое слово в коде и нажимаю Ф1.

теперь понятно что это некая альтернатива. только не понятно object поддерживает наследование как class?
object - не поддерживает конструкторы и деструкторы, нужно вызывать new и dispose, но наверное объект описанный как object работает несколько быстрее, поскольку вся эта гирлянда методов с TОbject не тянется как у classa.
Warn вне форума Ответить с цитированием
Старый 04.11.2011, 12:43   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
теперь понятно что это некая альтернатива.
object это корень.
Код:
type TObject=object
Это совместимость с паскалем, в нем было именно так.
Цитата:
только не понятно object поддерживает наследование как class?
Поддерживает.
Цитата:
object - не поддерживает конструкторы и деструкторы,
Поддерживает(вроде), синтаксис работы тот же.
Просто в нем нет ничего изначально, ни деструктора, ни конструктора.

Так же можно с ними работать как с записями(так же через New/Dispose создавать/удалять)
Цитата:
спасибо, но интересно где эта справка? у меня выводиться сообщение об ошибке если, если я выделю ключевое слово в коде и нажимаю Ф1.
у меня от Д6.
Цитата:
но наверное объект описанный как object работает несколько быстрее, поскольку вся эта гирлянда методов с TОbject не тянется как у classa.
Там разница лишь с созданием и удалением. чуток дольше(пара нс)
Тем не менее TObject гибче.

и еще:
Цитата:
Object types are supported for backward compatibility only. Their use is not recommended.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 04.11.2011, 13:34   #5
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Справку можно всегда увидеть здесь. В частности: classes and objects.

Ошибка по F1 - смотря какая ошибка. Возможно, справка просто не установлена.

object - это устаревшая конструкция, наследуемая Delphi из Borland Pascal-я. Грубо говоря, это записи с методами и наследованием. Весьма ограничены. Кроме того, поскольку эта конструкция оставлена в языке только по соображениям обратной совместимости, то её особо не тестируют и там полно багов. Лучше держаться от них подальше.

Основная разница между class и object (помимо более широких возможностей первого): class - это указатель (размещается в куче), object - это запись (размещается на стеке).

Цитата:
наверное объект описанный как object работает несколько быстрее, поскольку вся эта гирлянда методов с TОbject не тянется как у classa
Если вас волнуют эти копейки, то это явный признак того, что вы что-то делаете неправильно. Вероятно, вместо кучи мелких объектов нужно ввести один: объект-список.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 04.11.2011, 13:35   #6
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

Цитата:
Там разница лишь с созданием и удалением. чуток дольше(пара нс)
я попытался написать тест, чтобы проверить насколько и очевидна ли разница в доступе к полям и функциям класса и объекта.

вот что из этого получилось, и надо заметить что итераций у объекта больше в среднем в 2 раза.
inline - директива несколько помогает выправить ситуацию, но тем не менее перевес по скорости доступа к членам ... на стороне объекта.

Код:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

type CBox=class
public
     _x,_y,_z:Integer;
     constructor Create();overload;
     constructor Create(x,y,z:Integer);overload;

     function GetVolume():Integer;


end;

constructor CBox.Create();
begin
     self.Create(0,0,0);
end;
constructor CBox.Create(x,y,z:Integer);
begin
   _x:=x;
   _y:=y;
   _z:=z;

end;

function CBox.GetVolume():Integer;
begin
     result :=_x*_y*_z;
end;


type OBox=object
public
     _x,_y,_z:Integer;
     constructor Create();overload;
     constructor Create(x,y,z:Integer);overload;

     function GetVolume():Integer;
end;


constructor OBox.Create();
begin
     self.Create(0,0,0);
end;
constructor OBox.Create(x,y,z:Integer);
begin
   _x:=x;
   _y:=y;
   _z:=z;
end;

function OBox.GetVolume():Integer;
begin
     result :=_x*_y*_z;
end;


var
b1:CBox;
b2:OBox;
t:Integer;
i:Cardinal;
c:Cardinal=0;
begin

// Тест скорости доступа к полям и ф-ии класса
t:=GetTickCount()+2000;
b1:=CBox.Create();

while (t>=GetTickCount()) do begin
      b1._x:=100;
      b1._y:=50;
      b1._z:=2;

      for i := 0 to 1000 do
      begin
        b1.GetVolume();
      end;

      inc(c);
end;
b1.Free;
write('Class interations:');
writeln(c);



// Тест скорости доступа к полям и ф-ии объекта
t:=GetTickCount()+2000;
b2.Create();

while (t>=GetTickCount()) do begin
      b2._x:=100;
      b2._y:=50;
      b2._z:=2;
      for i := 0 to 1000 do
      begin
        b2.GetVolume();
      end;
      inc(c);
end;
write('Object interations:');
writeln(c);


readln;
end.

Последний раз редактировалось Warn; 04.11.2011 в 13:49.
Warn вне форума Ответить с цитированием
Старый 04.11.2011, 14:00   #7
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Наивный :-D

Кто ж так делает.

Эти два куска кода генерируют почти идентичный машинный код:

b1._x:=100;
005107DA C7400464000000 mov [eax+$04],$00000064
b1._y:=50;
005107E1 C7400832000000 mov [eax+$08],$00000032
b1._z:=2;
005107E8 C7400C02000000 mov [eax+$0c],$00000002
b1.GetVolume();
005107EF E814FFFFFF call CBox.GetVolume

b2._x:=100;
00510802 C745F464000000 mov [ebp-$0c],$00000064
b2._y:=50;
00510809 C745F832000000 mov [ebp-$08],$00000032
b2._z:=2;
00510810 C745FC02000000 mov [ebp-$04],$00000002
b2.GetVolume();
00510817 8D45F4 lea eax,[ebp-$0c]
0051081A E885FFFFFF call OBox.GetVolume

Как видим, код на object оказался даже больше на 1 инструкцию.

А твоя разница в результатах объясняется тем, что у тебя погрешность изменения больше его точности.

1. Вызов GetTickCount стоит дороже установки свойств и вызова GetVolume.
2. Начало одного цикла может попасть на нечётную границу, а начало второго - на чётную. Вот и получится, что второй цикл будет впереди планеты всей. Но не потому, что его тело быстрее, а потому что само условие цикла быстрее выполняется.

Но не будет верно мерять и в инструкциях: далеко не всегда две инструкции выполняются медленнее одной. Машинная оптимизация - дело сложное и неоднозначное. Но самое главное правило тут:

"Преждевременная оптимизация - корень всех бед"

Не занимайся оптимизацией, пока у тебя нет проблемы. Вот когда будет конкретная проблема - вот тогда её надо будет решать. И решать её надо будет не согласно своим "я думаю, что вот это работает медленно и поэтому я это оптимизирую". Как показывает практика, ты почти всегда будешь не прав. Единственный верный ответ тебе может дать профайлер.

А та фигня, которой ты занимаешься, съест у тебя месяцы работы и даст прирост в 1 миллисекунду в час.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 04.11.2011, 14:59   #8
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

Цитата:
Наивный :-D
я бы сказал пытливый.
Цитата:
Кто ж так делает.
а как делают?
Цитата:
1. Вызов GetTickCount стоит дороже установки свойств и вызова GetVolume.
Согласен(ф-я win ядра ~ тормоза), но как мне кажется цена для обоих циклов одинаковая поэтому не в счет.
Цитата:
2. Начало одного цикла может попасть на нечётную границу, а начало второго - на чётную. Вот и получится, что второй цикл будет впереди планеты всей. Но не потому, что его тело быстрее, а потому что само условие цикла быстрее выполняется.
что за границы? есть желание просветить?

Цитата:
Но не будет верно мерять и в инструкциях: далеко не всегда две инструкции выполняются медленнее одной.
Ага.

Цитата:
Машинная оптимизация - дело сложное и неоднозначное.
Сложное да, но вполне однозначное и конкретно направленное.
Таких программистов мало - это почти герои умственного труда.
Надеюсь когда-нибудь вырасту до понимания ассемблера.

Цитата:
Но самое главное правило тут:
"Преждевременная оптимизация - корень всех бед"
тоже читал где-то в какой-то "дорогойбесполезнойумнойкниге".
ну в общем-то да, было бы чего оптимизировать Тут скорее идет попытка разобраться в скоростных хр-ках фундаментальных единиц трансляции языка, что в целом может повлиять на выбор стратегии разработки. И поэтому стратегия типа - пишем процедурно, с кучей ассемблерных вставок, тоже имеет право - быть, если создатели языка хорошо отдохнули когда его создавали.

однако, все это я зря и все равно придется пользоваться "тормознымигибкимиклассами" как-нибудь переживу))
Warn вне форума Ответить с цитированием
Старый 04.11.2011, 19:20   #9
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

http://www.ozon.ru/context/detail/id/1418882/
http://www.insidepro.com/rus/doc.shtml
http://wasm.ru/
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.

Последний раз редактировалось GunSmoker; 04.11.2011 в 19:24.
GunSmoker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Could not convert variant of type (Olestr) into type (Double) java_91 Общие вопросы Delphi 1 18.02.2011 18:46
The type name 'GreenShalControl' does not exist in the type Beton_net WPF, UWP, WinRT, XAML 0 15.02.2011 11:24
Could not convert variant of type (UnicodeString) into type (Double) postaveche БД в Delphi 11 13.12.2010 16:41
Ошибка " Record, object or class type required " (Запись, объектный или классический тип требовались) kta87 Помощь студентам 2 28.02.2010 10:04
Record, object or class type required @mazonk@ Помощь студентам 0 07.06.2009 13:03