Вниз
Скачать: CL | DM;

Класс как тип.   Найти похожие ветки 

← →
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 вся ветка

Скачать: CL | DM;



Память: 0.5 MB
Время: 0.015 c
11-11844
titnn
2003-04-15 22:59
2004.01.05
Почему DLL сделанная в KOL не работает ?


3-11819
new
2003-12-08 12:24
2004.01.05
dbloocupcombobox


14-12168
NetKnight
2003-12-10 00:03
2004.01.05
Пошевелим извилинами?


14-12133
Beaver
2003-12-13 14:21
2004.01.05
Глюки компиляции


3-11770
Тигренок
2003-12-09 20:52
2004.01.05
Обращение к Driverам BDE из программы




   Наверх