Форум: "Основная";
Текущий архив: 2004.01.05;
Скачать: [xml.tar.bz2];
ВнизКласс как тип. Найти похожие ветки
← →
Maxim Vetera (2003-12-19 12:25) [0]Доброе утро! Можно ли использовать класс как тип? Приведенный программный код дает результат, но при закрытии проложения возращает ошибку доступа к памяти.
type
TTree = class
public
H : Single;
procedure SomeProcedure;
end;
procedure TTree.SomeProcedure;
begin
beep;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
T1:TTree;
begin
T1.H:=3.2;
ShowMessage(FloatToStr(T1.H));
end;
← →
REA (2003-12-19 12:29) [1]T1 не создан. Это не Си, тут надо ручками вызывать конструктор и деструктор.
← →
Johnmen (2003-12-19 12:30) [2]А что такое T1 ???????????????????
← →
PVOzerski (2003-12-19 12:36) [3]Так можно использовать объекты стиля TP, при условии неиспользования виртуальных методов.
← →
Рамиль (2003-12-19 12:36) [4]
procedure TForm1.Button1Click(Sender: TObject);
var
T1:TTree;
begin
T1 := TTree.Create;
T1.H:=3.2;
ShowMessage(FloatToStr(T1.H));
end;
Ну и не забыть уничтожить потом.
← →
Семен Сорокин (2003-12-19 12:38) [5]TTree = class
public
H : Single;
class procedure SomeProcedure;
end;
← →
Holy (2003-12-19 12:38) [6]Можно использовать. Но корректно в твоем случае будет писать:
procedure TForm1.Button1Click(Sender: TObject);
var
T1:TTree;
begin
T1:=TTree.Create;
T1.H:=3.2;
ShowMessage(FloatToStr(T1.H));
T1.Free;
end;
← →
Юрий Зотов (2003-12-19 12:40) [7]> Семен Сорокин © (19.12.03 12:38) [5]
А почему обязательно class ?
← →
PVOzerski (2003-12-19 12:48) [8]> Семен Сорокин © (19.12.03 12:38) [5]
> Юрий Зотов © (19.12.03 12:40) [7]
Имеется в виду, что class procedure можно вызывать, если нет экземпляров соответствующего класса. Но только что тогда делать с полем H? Ведь переменная типа class - не более чем указатель, и без присвоения ей результата вызова конструктора это в лучшем случае nil, а в худшем...
← →
Семен Сорокин (2003-12-19 12:52) [9]ИМХО class procedure необходим для того чтобы сделать статичной эту процедуру, сответсвенно можно будет вызывать без создания самого объекта. Поправьте если не прав.
← →
Maxim Vetera (2003-12-19 12:53) [10]В теории ООП иерархия классов дожна быть также и иерархией типов.
Я это понимаю как возможность использование классов как типов, т.е. не использовать конструктор-деструктор, а хотя бы иметь возможность работать с ними как с записями (обращаться к полям). Приведенный пример дает ведь ожидаемый результат, при этом значение свойства T1.H храниться в регистре ebx, равно как и с использованием конструктора
T1:=TTree.Create;
T1.H:=3.2;
ShowMessage(FloatToStr(T1.H));
T1.Free;
← →
Reindeer Moss Eater (2003-12-19 12:54) [11]Конструктор нужен если хочешь работать с экземпляром класса.
Если хочешь работать с классом, конструктор не нужен.
← →
PVOzerski (2003-12-19 13:04) [12]Я еще раз говорю: неинициализированный экземпляр класса не будет содержать поле H. И что можно вот так:
TTree = OBJECT
public
H : Single;
procedure SomeProcedure;
end;
← →
Maxim Vetera (2003-12-19 13:16) [13]
> PVOzerski © (19.12.03 13:04)
Да, но ShowMessage(FloatToStr(T1.H)) выводит таки на экран 3.2 ?
← →
PVOzerski (2003-12-19 13:22) [14]>Да, но ShowMessage(FloatToStr(T1.H)) выводит таки на экран 3.2 ?
Ага, а потом приложение валится с сообщением о EAccessViolation... С чего бы? :^)
ЗЫ: не поленился, проверил.
← →
yo (2003-12-19 13:24) [15]переменная типа TTree - это указатель,
указывающий в твоём случае на какой-то мусор или память,
используемую кем-то другим.
Ты её портишь. Вот и всё.
PS ты неправильно интерпретируешь слово тип.
← →
PVOzerski (2003-12-19 13:28) [16]В продолжение разговора:
Глянул я дебагером на T1 (а мог бы и не гладеть, если бы помнил точно, что из локальных переменных Delphi обнуляет по умолчанию). Так вот: указатель T1 содержит "мусор" из stackframe, этот мусор трактуется как некий адрес, по смещению от которого при присвоении пишется это 3.2. А уж куда при этом всё это попадает, какие данные портит - это никто вам не скажет...
← →
Романов Р.В. (2003-12-19 13:32) [17]В дополнение к yo (19.12.03 13:24) [15]
var
T1:TTree;
begin
T1 := nil;
T1.H:=3.2;
ShowMessage(FloatToStr(T1.H));
end;
← →
Maxim Vetera (2003-12-19 13:36) [18]Всем спасибо.
> PVOzerski ©
Спасибо.
← →
Юрий Зотов (2003-12-19 13:38) [19]> Семен Сорокин © (19.12.03 12:52) [9]
> ИМХО class procedure необходим для того чтобы сделать
> статичной эту процедуру, сответсвенно можно будет вызывать без
> создания самого объекта. Поправьте если не прав.
Что значит "сделать статичной" - непонятно, но классовые методы действительно можно вызывать без создания экземпляра объекта (именно по той причине, что такие методы не должны обращаться к полям объекта).
Однако же, какое это имеет отношение к сабжу? Никакого. Человек не создал объект и, естественно, при обращении к его полю получил ошибку (попытка обращения к "левому" адресу). Вот и вся причина.
И никакие class (или не class) здесь ни при чем.
← →
Alexander Vasjuk (2003-12-19 18:41) [20]Можно посоветовать вместо поля использовать статическую функцию, но "инициализировать" ее конечно нельзя.
В dotNET существуют статические поля классов. Их можно инициализировать, но в экземплярах изменить нельзя.
Я вот к чему.
В компиляторе от Borland для CLR эта фича интересно будет?
← →
Viktor Kushnir (2003-12-19 20:03) [21]Сорри, что встреваю, но помнится в 7 турбо паскале можно было статические обьекты делать и работать с ними, что урезали эту фичу?
← →
Тимохов (2003-12-19 20:05) [22]Viktor Kushnir © (19.12.03 20:03) [21]
И интересно как? Разве там такое можно было делать.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.01.05;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.008 c