Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2003.08.11;
Скачать: [xml.tar.bz2];

Вниз

Class Function....   Найти похожие ветки 

 
3APA3A   (2003-07-17 13:07) [0]

Почему так?
class1=class(TMySuperClass)
class function Get:boolean;
end;

1) var a:class1;
begin
if a.get then...
end. // Никакой ошибки.
2) var a:class1;
begin
a:=nil;
if a.get then...
end. // EAccessViolation...

Что фактически происходит при объявлении функции как class?
Не может же конструктор моего класса вызываться неявно, может быть вызвывается конструктор TObject? Объясните pls...


 
3APA3A   (2003-07-17 13:19) [1]

Ну кто-то ведь должен знать =)...


 
Skier   (2003-07-17 13:24) [2]

>3APA3A © (17.07.03 13:19)
Ты по обнулённому указателю обращаешся ?!


 
Юрий Федоров   (2003-07-17 13:32) [3]

Очень странно. Почему-то в первом случае
mov eax, [ebx]
во втором
mov eax, [eax]

в eax соответственно 0
Что они там накомпилировали ???


 
Mike_Goblin   (2003-07-17 13:36) [4]

In the defining declaration of a class method, the identifier Self represents the class where the method is called (which could be a descendant of the class in which it is defined). If the method is called in the class C, then Self is of the type class of C. Thus you cannot use Self to access fields, properties, and normal (object) methods, but you can use it to call constructors and other class methods.
A class method can be called through a class reference or an object reference. When it is called through an object reference, the class of the object becomes the value of Self.


 
VD602   (2003-07-17 17:28) [5]

Правильнее писать TClass1.Get, так как Get относится не к конкретному экземпляру, а к классу вцелом


 
Юрий Зотов   (2003-07-17 18:30) [6]

3APA3A © (17.07.03 13:07)

> Что фактически происходит при объявлении функции как class?

Такие методы (их называют классовыми) в качестве неявного параметра Self получают ссылку не на экземпляр объекта, а на его класс. Поэтому, если внутри классового метода нет обращения к полям объекта (а они именно так и пишутся), то экземпляр ему вовсе не нужен и такой метод может быть выполнен без создания экземпляра, через ссылку на его класс, а не на экземпляр - то есть, вызовом TMyObject.MyMethod, а не MyObject.MyMethod.

> Не может же конструктор моего класса вызываться неявно, может
> быть вызвывается конструктор TObject?

Никакой конструктор у Вас вовсе не вызывается и никакой объект вовсе не создается, а вместо этого вызывается классовый метод через ссылку на класс. В первом случае она корректна и все проходит ОК, а во втором случае Вы ее обнуляете - отсюда и AV.


 
Юрий Федоров   (2003-07-17 18:37) [7]

>>Юрий Зотов © (17.07.03 18:30)
>>В первом случае она корректна и все проходит ОК
Это почему же ? Это же ссылка не на класс, а на экземпляр класса :-(


 
Skier   (2003-07-17 18:45) [8]

>Юрий Федоров © (17.07.03 18:37)
Ссылка будет на экземпляр после того как конструктор отработает.


 
Юрий Федоров   (2003-07-17 18:50) [9]

>>Skier © (17.07.03 18:45)
Хорошо, помещаем переменную А не в стек, а делаем ее глобальной, получаем тот же AV
По твоему, это правильно ?

ЗЫ Я не спорю, что вызывать метод нужно через TMyClass


 
Ученик   (2003-07-17 19:15) [10]

>3APA3A © (17.07.03 13:07)

Согласен с Юрий Федоров ©

> var a:class1;
> begin
> if a.get then...
> end. // Никакой ошибки

Удачное состояние стека


 
Ученик   (2003-07-17 19:23) [11]

class function class1.Get:boolean;
begin
ShowMessage(ClassName)
end;

:-)



 
Юрий Федоров   (2003-07-17 19:25) [12]

>>Ученик © (17.07.03 19:23)
>>Удачное состояние стека

А вот и нет :-)
см. Юрий Федоров © (17.07.03 13:32)



 
Ученик   (2003-07-17 19:29) [13]

>Юрий Федоров © (17.07.03 19:25)
Ученик © (17.07.03 19:23)


 
Юрий Федоров   (2003-07-17 19:42) [14]

>>Ученик © (17.07.03 19:29)
Забавно :-) типа "TForm1" :-)


 
Fantasist.   (2003-07-17 21:45) [15]


> А вот и нет :-)
> см. Юрий Федоров © (17.07.03 13:32)


А вот и да! И Юрий Федоров © (17.07.03 13:32) только подтверждает это.

a.get;

move eax,[eax]
call class1.get


По моему, значение записанное в eaх не используется в самой функции (в смысле, оно читается, но функционально не используется). Но в еax лежит а, и если а=0 то получаем AV на прочтение по нулевому адресу. Есдли переменная глобальная, то она обнулена изначально компилятором, если же нет, то в нем находиться какое-то случайное значение, которое и берется как адрес значения, которое попадает в eax.


 
3APA3A   (2003-07-25 03:10) [16]

То есть переменная "a" инициализируется компилятором как ссылка на таблицу методов класса, и только после конструктора - на экземпляр класса?


 
default   (2003-07-25 03:38) [17]

3APA3A © (25.07.03 03:10)
читай Fantasist-а он всё верно написал
ещё раз: если переменная объекта - глобальная переменная, то она
обнуляется компилятором
и строки
MOV EAX, Obj
MOV EAX, [EAX]
приведут в AV-у на второй строке этого кода - обращение по нулевому адресу
эти строки формирует компилятор если метод вызывается через переменную типа Obj.Method
если переменная объекта объявлена в стеке, то эти строки могут "проскочить" если адрес попадётся "удачный" и до вызова метода дело дойдёт


 
default   (2003-07-25 03:40) [18]

"если переменная объекта объявлена в стеке"
внутри подпрограммы имеется ввиду



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2003.08.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.007 c
14-33352
N&N
2003-07-25 08:18
2003.08.11
Где найти FireBird-1.5


14-33275
SergeySEM
2003-07-25 15:50
2003.08.11
Как запустить прогу на уд.компе


1-33124
Сорокин Семен
2003-07-30 10:37
2003.08.11
FormatCurr


7-33372
Mihey
2003-05-23 18:16
2003.08.11
USB


3-33066
steelpunk
2003-07-17 17:10
2003.08.11
В DbGrid вместо русских букв диез(#)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский