Форум: "Основная";
Текущий архив: 2004.07.18;
Скачать: [xml.tar.bz2];
ВнизClass Functions Найти похожие ветки
← →
SPeller © (2004-07-06 07:12) [0]Всем доброго времени суток.
Я вот что-то не могу понять чем отличаются функции, объявленные какclass function FuncName ()
? Буду очень благодарен за разъяснение что это такое и с чем его едят.
← →
MBo © (2004-07-06 07:19) [1]Хелп по Class methods.
Они работают не с экземпляром объекта, а с самим классом, так что не требуют создания объекта, но в них нельзя использовать поля и т.д. Пример - TObject.ClassName
← →
SPeller © (2004-07-06 07:23) [2]Это я тоже читал, что с классами работают. Вот только не могу понять, как это?
На счет того что не требуют создания класса - дык, можно и обычный метод класса вызвать без создания объекта без проблем.
← →
MBo © (2004-07-06 07:26) [3]>обычный метод класса вызвать без создания объекта без проблем.
????
И что будет:
s:TStringList;
begin
s.add("a");
← →
SPeller © (2004-07-06 07:36) [4]А то что метод обращается к полям - это уже его проблема. Вызывается ведь. И в чем тогда отличие в запрете обращений к полям классовых функций и необходимости отсутствия обращений к полям класса простых методов чтобы небыло ошибки?
Вот живой пример:type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
function SomeFunc: Integer;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
function TForm1.SomeFunc: Integer;
begin
Result := 5;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
F: TForm1;
begin
Caption := IntToStr(F.SomeFunc);
end;
Отработает и ни на что не ругнётся, потому что к полям объекта нет обращений внутри функции. Ей абсолютно пофиг что в EAX мусор, она всё-равно туда результат запишет.
← →
TUser © (2004-07-06 07:52) [5]В живом примере тоже вызывается конструктор, просто Борланд освободил тебя от этих забот.
А отличаются они примерно так. Возьмем объект "программист Delphi". Его можно просклонять (один программист, много программисток), это - мотод класса. А вот напоить пивом можно только конкретный экземпляр программиста.
← →
MBo © (2004-07-06 08:06) [6]обычный метод представляет собой структуру TMethod, содержащую указатели на адрес данной функции в классе (Code), и указатель на сам объект (Data), по этому адресу хранятся данные конкретного экземпляра (выделение памяти осуществляется при вызове конструктора классовой функцией NewInstance). Self в обычно методе - указатель на экземпляр объекта, в классовом - на сам класс.
← →
SPeller © (2004-07-06 08:32) [7]
> TUser © (06.07.04 07:52) [5]
> В живом примере тоже вызывается конструктор, просто Борланд
> освободил тебя от этих забот.
Нет, ничего там не вызывается. Проверьте сами, если не верите.
> MBo © (06.07.04 08:06) [6]
> в классовом - на сам класс
То есть, на саму структуру класса, по которой создаются все экземпляры класса?
← →
MBo © (2004-07-06 08:46) [8]>То есть, на саму структуру класса, по которой создаются все экземпляры класса?
Да, можно так сказать.
← →
TUser © (2004-07-06 08:47) [9]
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
Instance: TComponent;
begin
Instance := TComponent(InstanceClass.NewInstance);
TComponent(Reference) := Instance;
try
Instance.Create(Self);
except
TComponent(Reference) := nil;
raise;
end;
if (FMainForm = nil) and (Instance is TForm) then
begin
TForm(Instance).HandleNeeded;
FMainForm := TForm(Instance);
end;
end;
ЗЫ. Объект Форма не может возникнуть сам собой - без конструктора.
← →
SPeller © (2004-07-06 08:56) [10]
> Да, можно так сказать.
А можно по указателю, который передается на эту структуру, определить размер этой структуры, т.е. если бы мы вручную выделяли память под класс, то можно ли и как узнать сколько памяти надо?
← →
KSergey © (2004-07-06 08:57) [11]> [9] TUser © (06.07.04 08:47)
Вы в код из [4] SPeller © (06.07.04 07:36) внимательно вчитаетесь наконец?
А то, что "живой пример" работает - я склонен списать на случайности. В общем случае не любой указатель является заведомо таким, что обязтельно будет AV.
← →
SPeller © (2004-07-06 08:58) [12]
> TUser © (06.07.04 08:47) [9]
Посмотрите внимательно на этот кусок кода:var
F: TForm1;
begin
Caption := IntToStr(F.SomeFunc);
Где здесь что-либо создается?
← →
SPeller © (2004-07-06 09:02) [13]
> А то, что "живой пример" работает - я склонен списать на
> случайности
Нет, это не случайность. Я могу вам гарантировать что любой метод класса будет нормально работать в таких условиях только в том случае, если он не обращается к полям класса. Потому что при обращении к полям используется значение Self, которое содержит мусор, что и вызывает AV. Нет обращений к полям - нет обращений к Self - нет никаких AV.
← →
TUser © (2004-07-06 09:06) [14]Да, правда. Невнимателен был, прошу пардона.
← →
GuAV © (2004-07-06 11:43) [15]короче, напиши
var
C: TComponent
begin
C. {задумайся, всплывет подсказка, в ней все методы}
TComponent. {задумайся, всплывет подсказка, в ней только классовые методы}
← →
GuAV © (2004-07-06 11:48) [16]SPeller © (06.07.04 09:02) [13]
да. но чтобы не путать методы, которые не работают с полями и могут работать для несозданных классов с обычными вели класовые методы. и потом есть функции которым передается TClass или какойто ещё class of. и потом, у классового self"ом при вызове как классового в self будет class
← →
GuAV © (2004-07-06 11:57) [17]
> TClass или какойто ещё class of
> в self будет class
я имел ввдиу class-reference или metaclass.
Без этой фичи в Delphi они были бы бесполезны.
← →
Юрий Зотов © (2004-07-06 12:14) [18]> SPeller © (06.07.04 08:56) [10]
> А можно по указателю, который передается на эту структуру,
> определить размер этой структуры, т.е. если бы мы вручную
> выделяли память под класс, то можно ли и как узнать сколько
> памяти надо?
Можно: Self.InstanceSize.
В классовых методах неявный параметро Self - это ссылка на класс (в обычных - на экземпляр класса). InstanceSize - тоже классовый метод, поэтому его можно вызывать и через ссылку не класс.
← →
GuAV © (2004-07-06 12:51) [19]
> В классовых методах неявный параметро Self - это ссылка
> на класс (в обычных - на экземпляр класса)
Но если классовый метд вызван как обычный через экземпляр, то у него и self как у обычного.
← →
MBo © (2004-07-06 13:50) [20]>GuAV © (06.07.04 12:51) [19]
>Но если классовый метд вызван как обычный через экземпляр, то у него и self как у обычного.
Да ну? ;))
TC=class
class function ClassMe:Pointer;
function Me:Pointer;
end;
class function TC.ClassMe: Pointer;
begin
Result:=Self;
end;
function TC.Me: Pointer;
begin
Result:=Self;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
c:TC;
begin
c:=TC.Create;
Caption:=Format("%p %p %p",[TC.ClassMe,c.ClassMe,c.Me]);
c.Free;
end;
← →
Юрий Зотов © (2004-07-06 14:01) [21]> GuAV © (06.07.04 12:51) [19]
Очень похоже, что Delphi с Вами не согласна.
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
public
class procedure A;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
class procedure TForm1.A;
begin
if Self = TForm1 then
ShowMessage("класс")
else
ShowMessage("не класс")
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.A // И получаем сообщение "класс"
end;
А вот что показывает ассемблерный код Button1Click:
mov eax, [Form1] ; в eax - ссылка на экземпляр
mov eax, [eax] ; в eax - ссылка на класс
call TForm1.A ; и только теперь - вызов
Я полагаю, что компилятору верить можно...
:о)
← →
GuAV © (2004-07-06 14:07) [22]
> Очень похоже, что Delphi с Вами не согласна.
Извините, ошибся, хелп не правильно перевел :-(
← →
SPeller © (2004-07-06 17:00) [23]Большое всем спасибо за столь подробные разъяснения! Чтобы не докучать вопросами, было бы очень интересно самому почитать про внутреннюю организацию классов и объектов (object). Если кто подскажет где можно почитать буду очень благодарен. )
← →
Amoeba © (2004-07-06 17:02) [24]На сайте Анатолия Подгорецкого полно литературы.
← →
Тимохов © (2004-07-06 17:20) [25]
> SPeller © (06.07.04 17:00) [23]
ничего нет лучше, чем часто вызвать окно cpu (главное меню\view\debug windows) и см. асм код.
ЗЫ
я асм не знаю (совсем), но часто мне кажется, что что-то понимаю :))) Иногда ошибаюсь правда, но все же польза от изучения cpu есть
← →
Анонимщик © (2004-07-06 18:07) [26]Speller
Хелп на слово VMT. Остальное несложно сообразить. Полезно также посмотреть, что происходит при запуске программы, в частности,
InitExe, StartExe.
А также структуру PE-файла.
← →
Тимохов © (2004-07-06 18:10) [27]
> Анонимщик © (06.07.04 18:07) [26]
> InitExe, StartExe.
Где это можно посмотреть?
← →
Анонимщик © (2004-07-06 18:33) [28]Под отладчиком лучше всего и смотреть. Оно все в SysInit.pas
← →
SPeller © (2004-07-07 03:27) [29]
> А также структуру PE-файла.
Ой, мне ли вы это будете рассказывать? :-)))
> ничего нет лучше, чем часто вызвать окно cpu (главное меню\view\debug
> windows) и см. асм код.
АСМ код не покажет структуру сласса и расположение в ней элементов различных. А то что смотреть в окошко cpu полезно — я сам знаю :)
← →
Тимохов © (2004-07-07 08:54) [30]
> АСМ код не покажет структуру сласса и расположение в ней
> элементов различных.
это как смотреть: в свое время я именно так и понял много вещей.
← →
Анонимщик © (2004-07-07 11:11) [31]Почитав справку по VMT, ты поймешь, где находятся поля и методы по отношению к адресу класса или объекта, а из PE формата нужно только знать, как вытащить адрес сегмента кода и сегмента данных. После этого сам можешь построиь, например, дерево классов с адресами полей и т.д. С абсолютного нуля разберешься со всем за неделю, это точно.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.07.18;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.037 c