Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
1

Может ли быть вызвана объявленная, но неопределённая функция?

02.01.2012, 23:11. Показов 1896. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Друзья! Ещё раз прошу иизвнения, если задену чьи-то чувства, но в дельфи я полный профан.

...Итак, качнул исходники Dev-Cpp (IDE C++, прилагаются), написанные на Delphi7. Научился компилировать и даже нашёл, как мне кажется, процедуру, с которой и разбираюсь. (Эта процедура должна удалить настройки компилятора g++ по нажатию на кнопку, но она ни фига их не удаляет. То есть удаляет пункт в выпадающем списке с именем настроек, но не сами настройки)

Вот она:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TCompForm.btnDelCompilerSetClick(Sender: TObject);
begin
 
  //По моему это если остался единственный пункт настроек, то должен вылезти отказ в удалении, поэтому я  благополучно пропустил мимо глаз
  if cmbCompilerSetComp.Items.Count=1 then begin
    MessageDlg(Lang[ID_COPT_CANTDELETECOMPSET], mtError, [mbOk], 0);
    Exit;
  end;
 
  if MessageDlg(Lang[ID_COPT_DELETECOMPSET], mtConfirmation, [mbYes, mbNo], 0)=mrNo then
    Exit;
 
  //А вот здесь остановился
  devCompilerSet.Sets.Delete(cmbCompilerSetComp.ItemIndex);
  cmbCompilerSetComp.Items.Delete(cmbCompilerSetComp.ItemIndex);
  cmbCompilerSetComp.ItemIndex:=0;
  cmbCompilerSetCompChange(nil);
 
end;
Итак,
Delphi
1
devCompilerSet.Sets.Delete(cmbCompilerSetComp.ItemIndex);
Значит, я решил посмотреть реализацию Delete, но НЕ СМОГ ЕЁ НАЙТИ! Объявление есть есть:

Delphi
1
2
3
4
TStrings = class(TPersistent)
  ;всякие другие процедуры
 
  procedure Delete(Index: Integer); virtual; abstract;
А самого определения нет! Как же она реализована и реализована ли вообще?
НА всякий случай посмотрел класс TPersistent и ещё какой-то коленом выше, тоже этой функции нет

Потом посмотрел, что значит слова "virtual; abstract;"
"Директива Virtual может сопровождаться директивой Abstract. Это изменяет эффект директивы Virtual. Это означает, что текущий класс не должен кодировать метод - он здесь только как метка-заполнитель, чтобы напомнить и гарантировать, что полученные классы осуществят его. Директива Virtual может сопровождаться директивой Abstract. Это изменяет эффект директивы Virtual. Это означает, что текущий класс не должен кодировать метод - он здесь только как метка-заполнитель, чтобы напомнить и гарантировать, что полученные классы осуществят его. "

То есть мне щас надо для класса TStrings искать подкласс и она там должна быть определена, ну допустим. Но фишка в том, что devCompilerSet.Sets именно класса TStrings, а никакого другого, вот:

Delphi
1
property Sets: TStrings read fSets write fSets;
В общем надо как-то разобраться мне с этоф функцией Delete, которая объявлена, но не определена. Я не знаю, может ли в Delphi быть вызвана неопределённая функция, в С++ нет. И если я прав в своих догадках, надо будет получается самому реализовывать удаление настроек. Спасибо, кто окликнется.

Добавлено через 2 минуты
Вот исходники
https://www.cyberforum.ru/atta... 1325455643
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.01.2012, 23:11
Ответы с готовыми решениями:

Ошибка E2250 (Нет перегруженной версии 'FmtStr', которая может быть вызвана с этими аргументами)
Параметры процедуры: FmtStr(var StrResult: string; const Format: string; const Args: array of...

save_construct_data не хочет быть вызвана
Перегрузил функцию save_construct_data, но программа не хочет ее вызывать. namespace mymath...

Может ли рекурсивная функция быть встроенной?
сам знаю, что не может, а почему компилится без ошибок; видимо оно компилится как обычная?

Ошибка - функция не может быть перегружена
Добрый вечер! Первый раз пишу на этом форуме, я новичок, так что как можно понятнее объясняйтесь,...

18
474 / 337 / 36
Регистрация: 31.05.2011
Сообщений: 1,162
03.01.2012, 01:15 2
CodeIns.pas
Delphi
1
2
3
4
5
6
7
8
procedure TCodeInsList.Delete(index: integer);
begin
  if (index <0) or (index > fList.Count -1) then exit;
 
  fList.Delete(index);
  fList.Pack;
  fList.Capacity:= fList.Count;
end;
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
03.01.2012, 16:36  [ТС] 3
А как определить, что это именно эта функция и есть искомая? То есть я вижу определение метода Delete класса
TCodeInsList

Меж тем мне нужно определение Delete класса TStrings. Извините
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
03.01.2012, 19:05 4
Цитата Сообщение от kravam Посмотреть сообщение
Меж тем мне нужно определение Delete класса TStrings
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure TMemoStrings.Delete(Index: Integer);
const
  Empty: PChar = '';
var
  SelStart, SelEnd: Integer;
begin
  SelStart := SendMessage(Memo.Handle, EM_LINEINDEX, Index, 0);
  if SelStart >= 0 then
  begin
    SelEnd := SendMessage(Memo.Handle, EM_LINEINDEX, Index + 1, 0);
    if SelEnd < 0 then SelEnd := SelStart +
      SendMessage(Memo.Handle, EM_LINELENGTH, SelStart, 0);
    SendMessage(Memo.Handle, EM_SETSEL, SelStart, SelEnd);
    SendMessage(Memo.Handle, EM_REPLACESEL, 0, Longint(Empty));
  end;
end;
Если вам в дальнейшем понадобится делать просматривать подобные методы, в опциях проекта на вкладке Compiler включите Use Debug DCUs. И по f7/f8 попадете куда надо.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
03.01.2012, 19:57  [ТС] 5
Спасибо, конечно, но вопросы те же самые остались, то есть я наблюдаю определение метода Delete класса TMemoStrings, меж тем мне нужно определение метода Delete класса Tstrings
...НАсколько я понял, по F7/F8 мы просто пошагово выполняем программу, в общем я жал на F8 ища нужный метод, пока просто не запустил Dev-Cpp
Delphi
1
  Application.Run;
после этого Delphi7 прекратила реагировать на F8, а нужное определение я так и не нашёл.
0
480 / 253 / 51
Регистрация: 30.06.2010
Сообщений: 651
03.01.2012, 20:36 6
Найдите объявление в классе devCompilerSet где производится инстанцирование fSets (именно fsets) скорее всего найдёте в конструкторе Create, там будет что-то вроде fsets := Tstringlist.create;
Так вот, в этом Tstringlist и ищите описание метода Delete (само собой, там может быть не конкретно Tstringlist, я его поставил в пример, как фактического класса), т.е. будет вызываться не абстрактный метод формально прописанного класса, а перекрытый метод фактического класса.

F8 это step over - дебаг без захода в подпрограмму, а Вам надо использовать F7 - с заходом в подпрограмму. А ещё лучше сделать брейкпоинт по F5 - и нажать Run F9 и тогда при попытке выполнения кода программа брякнется туда, где поставили бряк, хотя думаю, Вы понимаете ход дебага в общих чертах.
1
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
03.01.2012, 23:40 7
Цитата Сообщение от kravam Посмотреть сообщение
нужно определение метода Delete класса Tstrings
TStrings абстрактный класс, для него существует только объявление метода Delete. Реализация отсутствует. Поэтому вы непосредственно "его" реализацию не найдете. Я своим прошлым постом пытался донести, что имея где-то в коде или переменную или тип возвращаемого результата в виде TStrings де-факто подразумевается любой потомок этого класса. В вашем конкретном случае, как справедливо заметил pHOMM вам нужно при помощи trace into попасть в вызов этой процедуры и смотреть что к чему.
1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
10.01.2012, 02:14  [ТС] 8
А без трассировки никак нельзя? Я просто не пойму, я ведь в этой строке когда нахожусь
Delphi
1
devCompilerSet.Sets.Delete(cmbCompilerSetComp.ItemIndex);
Потом правой кнопкой мыши тычу, а потом тычу "найти описание", я ведь имею ввиду описание конкретного участка кода, который будет вызван. Не абстрактного, а конкретного, потому что из этого места вызывается функция Delete, не абстрактная, а конкретная. А попадаю на невесть что:
Delphi
1
    procedure Delete(Index: Integer); virtual; abstract;
Я просто хочу узнать, может я что делаю не так? Если IDE не предоставляет такого сервиса, буду возиться с трассировкой, просто непонятно, ведь приведённая строка (первая) и та функция которая вызовется, ставятся друг другу в соответствие ОДНОЗНАЧНО (по крайней мере первая->второй), а поэтому странно не наблюдать в такой мощной среде нахождения этого соответствия в один клик. Ну или в два.

Добавлено через 49 минут
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Ребята, мне без вашей помощи не обойтись, короче я решил пошагово трассировать всю эту бодягу, итак, ставлю бряк два бряка, вот на этих строках:

Delphi
1
2
  devCompilerSet.Sets.Delete(cmbCompilerSetComp.ItemIndex);
  cmbCompilerSetComp.Items.Delete(cmbCompilerSetComp.ItemIndex);
Запуска. программу в Delphi7, делаю несколько лёгких пассов руками, жму куда надо и брякаюсь на первой из двух строк. Отлично, хочу посмотреть, что она из себя скрывает, реализацию тык скыть этой проклятой Delete. Жму на F7 и попадаю на этот участок кода:

Delphi
1
2
3
4
5
6
7
function TCustomCombo.GetItemIndex: Integer;
begin
  if csLoading in ComponentState then
    Result := FItemIndex
  else
    Result := SendMessage(Handle, CB_GETCURSEL, 0, 0);
end;
, не строчку begin, если быть точным. А теперь сдледите, что называется за руками. Во-первых, функция возвращает значение- уже настораживает, ибо в место вызова она ничё возвращать не должна. Ну да Бог с ней, может, издержки производства. Итак: ставлю бряк на end, жму на F9 и брякаюсь на нём. А теперь вопрос: куда я щас должен попасть по нажатию F7? Правильно, я подумал так же, вот сюда:
Delphi
1
cmbCompilerSetComp.Items.Delete(cmbCompilerSetComp.ItemIndex);
Но человек предполагает, а Бог располагает- по F7 я попадаю вообще непонятно куда:
Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure TStringList.Delete(Index: Integer);
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  Finalize(FList^[Index]);
  Dec(FCount);
  if Index < FCount then
    System.Move(FList^[Index + 1], FList^[Index],
      (FCount - Index) * SizeOf(TStringItem));
  Changed;
end;
На строчку begin. Всё, я ничё не понимаю. Если вся
Delphi
1
devCompilerSet.Sets.Delete(cmbCompilerSetComp.ItemIndex);
заключается в вызове TCustomCombo.GetItemIndex, то почему по покончании работы второй я не попадаю в основной код?

Добавлено через 28 минут
Уж я даже у этой проклятой Delete нашёл и ассемблерный код, брякнулся на неё, правой кнопкой-> отладка-> показать CPU; а исходник никак не найду
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
10.01.2012, 10:21 9
Присоединюсь к обсуждению темы.
Цитата Сообщение от kravam Посмотреть сообщение
Delphi
1
devCompilerSet.Sets.Delete(cmbCompilerSetComp.ItemIndex);
Потом правой кнопкой мыши тычу, а потом тычу "найти описание", я ведь имею ввиду описание конкретного участка кода, который будет вызван. Не абстрактного, а конкретного, потому что из этого места вызывается функция Delete, не абстрактная, а конкретная. А попадаю на невесть что:
Delphi
1
procedure Delete(Index: Integer); virtual; abstract;
Всё правильно, свойство devCompilerSet.Sets объявлено, как поле типа TStrings. Класс TStrings - это абстрактный класс. Это означает, что некоторые его методы объявлены, но не реализованы. Нереализованным является также и метод Delete(). В объявлении этого метода прямо указано на это с помощью слова: abstract. Нельзя создать экземпляр абстрактного класса. Можно создать экземпляр класса потомка от абстрактного класса, в котором реализованы все абстрактные методы. Абстрактный класс задаёт архитектурную, концептуальную основу для группы классов, которые будут унаследованы от него.
Цитата Сообщение от kravam Посмотреть сообщение
Но человек предполагает, а Бог располагает- по F7 я попадаю вообще непонятно куда:
Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure TStringList.Delete(Index: Integer);
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  Finalize(FList^[Index]);
  Dec(FCount);
  if Index < FCount then
    System.Move(FList^[Index + 1], FList^[Index],
      (FCount - Index) * SizeOf(TStringItem));
  Changed;
end;
Это означает, что полю devCompilerSet.Sets присвоен указатель на экземпляр класса потомка, унаследованного от класса TStrings. В данном случае классом-потомком является класс TStringList. Этот класс уже не является абстрактным и его метод Delete() имеет реализацию. Именно реализацию этого метода мы и видим в приведённом коде.
---
Здесь смысл в следующем. У нас есть поле evCompilerSet.Sets. Это поле может ссылаться на экземпляр любого не абстрактного класса, являющегося наследником от класса TStrings. Код построен так, что этому полю, evCompilerSet.Sets, присваивается указатель на экземпляр класса TStringList. Этот класс, TStringList, является потомком от класса TStrings.
---
Чтобы было понятнее можно рассмотреть такой пример. Предположим, что мы должны работать с такими компонентами как: TMemo, TListBox, TComboBox и с экземплярами класса TStringList. И нам надо написать процедуру, которая бы умела записывать в экземпляры этих классов набор случайных чисел (в строковом представлении). Все эти компоненты хранят свои текстовые данные в потомках класса TStrings. Зная это, пишем процедуру:
Delphi
1
2
3
4
5
6
7
8
9
10
procedure SetNewText(aSl : TStrings);
var
  i : Integer;
begin
  aSl.Clear;
  Randomize;
  for i := 1 to 5 + Random(10) do
    aSl.Add(IntToStr( Random(100) ))
  ;
end;
Эта процедура может обрабатывать данные экземпляров любых потомков класса TStrings. Т. е., в программе мы можем писать так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
var
  Memo1 : TMemo;
  ListBox1 : TListBox;
  ComboBox1 : TComboBox;
  StringList1 : TStringList;
begin
...
  SetNewText( Memo1.Lines );
  SetNewText( ListBox1.Items );
  SetNewText( ComboBox1.Items );
  SetNewText( StringList1 );
...
Здесь, при каждом таком вызове, в процедуру SetNewText() под видом параметра aSl каждый раз будут передаваться указатели на экземпляры различных классов. Общее этих экземпляров в том, что все они являются экземплярами классов, которые в дереве своих предков содержат класс TStrings.
kravam, в этом примере последняя строка:
Delphi
1
  SetNewText( StringList1 );
это, как раз, случай подобный твоему. Т. е., имеем параметр aSl, принадлежащий типу TStrings. И если ты попытаешься найти какой-то метод, связанный с aSl, то будешь попадать на объявления методов класса TStrings. Какие-то из этих методов могут не иметь реализации, если они являются абстрактными. А если запустишь программу и попытаешься выйти на методы, связанные с экземпляром aSl, то попадёшь на реализацию того класса, к которому принадлежит экземпляр, переданный через параметр aSl. Т. е., если в коде имеем строку:
Delphi
1
  SetNewText( StringList1 );
то, в данном случае, aSl = StringList1 и значит, будем иметь дело с классом TStringList.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
10.01.2012, 13:33  [ТС] 10
Спасибо, что-то понятно, над чем-то ещё буду думать, но один вопрос для дальнейшего продвижения высянить необходимо.
+++
Напомню, по бряку на этом вызове:
Delphi
1
  devCompilerSet.Sets.Delete(cmbCompilerSetComp.ItemIndex);
Мы наблюдаем последовательную работу двух функций:

Delphi
1
2
3
4
5
6
7
function TCustomCombo.GetItemIndex: Integer;
begin
  if csLoading in ComponentState then
    Result := FItemIndex
  else
    Result := SendMessage(Handle, CB_GETCURSEL, 0, 0);
end;
и

Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure TStringList.Delete(Index: Integer);
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  Finalize(FList^[Index]);
  Dec(FCount);
  if Index < FCount then
    System.Move(FList^[Index + 1], FList^[Index],
      (FCount - Index) * SizeOf(TStringItem));
  Changed;
end;
...Про вторую вы мне всё объяснили, а первую куда девать? Так-то я понимаю, что в принципе реализация какого-нибудь метода может включать в себя сколь угодно вызовов каких угодно функций. А раз так, то, получается что по указанному бряку вызывается вот эта реализация (псеводокод):

Delphi
1
2
3
4
procedure_или_function <тут_имя_процедуры_или_функции> begin
 function TCustomCombo.GetItemIndex;
 procedure TStringList.Delete;
end;
...Ну то есть то, что вы сказали,
Этот класс уже не является абстрактным и его метод Delete() имеет реализацию. Именно реализацию этого метода мы и видим в приведённом коде.
Но с поправкой: не всю реализацию, а только её часть. А как найти всю? Смысл поиска вот в чём: просто планирование работы, хорошо, тут всего два вызова:
Delphi
1
2
 function TCustomCombo.GetItemIndex;
 procedure TStringList.Delete;
И я их обнаруживаю трассировкой. Так, а в другой раз их может быть 20 штук, не натрассируешься! Вот хотелось бы глянуть: ага, вот тут 20 вызово различных функций, вот судя по названиям надо обратить внимание на эту и эту.
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
10.01.2012, 14:05 11
Цитата Сообщение от kravam Посмотреть сообщение
Вот хотелось бы глянуть: ага, вот тут 20 вызово различных функций, вот судя по названиям надо обратить внимание на эту и эту.
Если нужно узнать что откуда и сколько раз вызывается, здесь надо либо изучать исходный код используемых классов, либо - трассировкой.
Цитата Сообщение от kravam Посмотреть сообщение
Так, а в другой раз их может быть 20 штук, не натрассируешься!
Ну от этого никуда не деться - чем больше код, тем сложнее в нём разбираться. В общем, "копать глубоко" нужно начинать в случае, если программа работает в самом деле медленно и требуется что-то предпринять для увеличения быстродействия.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
10.01.2012, 14:28  [ТС] 12
А в моём случае код какого класса надо изучить?
То есть я правильно понял, что где-то до этого вызова
Delphi
1
  devCompilerSet.Sets.Delete(cmbCompilerSetComp.ItemIndex);
Существует такое примерно присваивание:
Delphi
1
devCompilerSet.Sets= <а здесь находится адрес объект класса X, который производный от класса TStrings>
И в этом классе X и есть реализация Delete? Найти такое присваивание мне не под силу, наверное, но мне хоть надо знать, правильно я понял или нет.

+++++++++++++++++++++++++++++++++++++++

Там недостатки те ещё, там предлагаются несколько настроек компиляотора, например:
настройка_A, настройка_B, настройка_C;
каждая настройка суть набор опций, с которыми компилятор запускается. Можно свои обавлять или менять. А вот удалить проблема, допустим, удаляю настройку
настройка_B

Остаются настройки:
настройка_A, настройка_C;

И всё бы ничего, да только вот набор опций настройка_C исчезает бесследно, а на его месте оказывается набор опций удалённой настройки настройка_B

Добавлено через 3 минуты
Цитата Сообщение от Mawrat Посмотреть сообщение
Если нужно узнать что откуда и сколько раз вызывается, здесь надо либо изучать исходный код используемых классов, либо - трассировкой.
И кстати, в моём случае надо только исходный код изучать потому что по трассировке мы попадаем на два вызова, о которых я говорил, но фишка-то в том, что они могут вызываться не безусловно, а по каким-то условиям. То есть: предположим теоретически, что я поправил работу какой-то из двух функций, а она взялась и не выщзвалась в один прекрасный момент, ибо вызывается ПО НЕКОТРОМУ УСЛОВИЮ. Вся работа насамарку.
0
13104 / 5885 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
10.01.2012, 14:41 13
Цитата Сообщение от kravam Посмотреть сообщение
Существует такое примерно присваивание:
Delphi
1
devCompilerSet.Sets= <а здесь находится адрес объект класса X, который производный от класса TStrings>
И в этом классе X и есть реализация Delete? Найти такое присваивание мне не под силу, наверное, но мне хоть надо знать, правильно я понял или нет.
Да, верно. И выше в теме об этом уже говорили HighPredator и pHOMM. - Что такое присвоение следует искать, начиная с реализации конструктора класса, к которому принадлежит экземпляр devCompilerSet. И таким потомком класса TStrings, судя по:
Цитата Сообщение от kravam Посмотреть сообщение
по F7 я попадаю вообще непонятно куда:
Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure TStringList.Delete(Index: Integer);
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  Finalize(FList^[Index]);
  Dec(FCount);
  if Index < FCount then
    System.Move(FList^[Index + 1], FList^[Index],
      (FCount - Index) * SizeOf(TStringItem));
  Changed;
end;
является класс TStringList.
1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
10.01.2012, 16:01  [ТС] 14
Кажется, вы были правы, расставляя бряки подобного рода
ShowMessage(IntToHex(Integer(devCompilerSet.Sets), 8)+ 'попробуем здесь');
то здесь, то там:

Я наткнулся на:
Delphi
1
  devCompilerSet:= TdevCompilerSet.Create;
, а потом:

Delphi
1
2
3
4
5
6
7
constructor TdevCompilerSet.Create;
begin
  inherited;
  fSets:=TStringList.Create;
  UpdateSets;
  SettoDefaults;
end;
TStringList нашёл, TStringList.Delete нашёл, правда там код посложнее будет, чем два последователных вызова, но как я предполагал, там условия всякие, по их оброаботке на выходе из компилятра и получаются два вызова. Попробую разобраться, спасибо!
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
10.01.2012, 16:17 15
Ну и тема. Умеет ли комп "ходить туда, не скажу как". А как он пойдёт, если ему не сказали, как это делается? Куда, он предположим знает. Но если ты забыл ему сказать, как, то чего ты от него хочешь?
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
10.01.2012, 16:18  [ТС] 16
Так-то я разобрался уже. До свидания.
0
159 / 152 / 50
Регистрация: 03.08.2011
Сообщений: 299
Записей в блоге: 14
10.01.2012, 16:22 17
Цитата Сообщение от kravam Посмотреть сообщение
...Про вторую вы мне всё объяснили, а первую куда девать? Так-то я понимаю, что в принципе реализация какого-нибудь метода может включать в себя сколь угодно вызовов каких угодно функций. А раз так, то, получается что по указанному бряку вызывается вот эта реализация (псеводокод):
Delphi
1
2
3
4
procedure_или_function <тут_имя_процедуры_или_функции> begin
 function TCustomCombo.GetItemIndex;
 procedure TStringList.Delete;
end;
Здесь всё веселее.В коде вызывается ЧтоТоТам.Delete(ЧтоТоЕщё.ItemIndex), однако ЧтоТоЕщё.ItemIndex - это не переменная, а свойство. Посмотрите его определение, и увидите что-то вроде:
Delphi
1
2
3
4
5
6
private
  function GetItemIndex:Integer;
  procedure SetItemIndex(Value:Integer);
  {...}
published
  property ItemIndex:Integer read GetItemIndex write SetItemIndex;
то есть когда вы пытаетесь узнать значение ItemIndex, вы на самом деле узнаёте результат функции GetItemIndex, а когда пытаетесь записать что-то в ItemIndex, вы на самом деле вызываете процедуру SetItemIndex и передаёте ей то, что пытаетесь записать. Соответственно, перед вызовом Delete вызывается GetItemIndex, чтобы узнать, что в Delete передавать.
1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
10.01.2012, 16:38  [ТС] 18
Понимаемо. Здорово, конечно, если бы это можно было увидеть в исходниках, но это отошло уже на второй план, ведь я КОРРЕКТНО (не наугад то есть) нужную реализацию Delete, а это главное. А этот механизм, что вы описали наверное скрыт где-то в её глубине.

Добавлено через 11 минут
вот тогда у меня возник вопрос, а чё, компилятор скам подставляет
SetItemIndex?
То есть тут важно понять, что я имею ввиду, то есть я понимаю, чтокомпилятор много
чего куда подставляеть сам и это скрыто. В С++ также, но там он только может
подставить функцию в АССЕМБЛЕРНЫЙ КОД (если она, конечно не реализована в хидерах)! А тут мы наблюдаем вызов
SetItemIndex (суть нахождения индекса) в исходном коде.

То есть автор просто прописал
TStringList.Delete(Index: Integer);

И вместо Index: Integer пишется вызов
SetItemIndex(Value:Integer), так?


+++++++++++++++++++++++++++++++++++++++++++++++++++++++

Ну или раз уж об этом разговор зашёл, наверное в DElphi есть хидеры и
SetItemIndex(Value:Integer) реализована в хидерах? ТОгда это всё объясняет. Но, кажись,
Она реализована не в хидерах, а в авторских сырцах, мне не разобраться.
0
159 / 152 / 50
Регистрация: 03.08.2011
Сообщений: 299
Записей в блоге: 14
10.01.2012, 17:22 19
для примера, класс представляет строку из единиц
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
type
  TOne=class
  private
    FCount:Integer;
    procedure SetCount(v:Integer);
    function GetCount:Integer;
    function ToString:string;
    procedure SetCountFromStr(v:String);
  public
    constructor Create;
    property Count:Integer read GetCount write SetCount;
    property AsString:String read ToString write SetCountFromStr;
  end;
  
procedure TOne.SetCount(v:Integer);
begin
  if v>0 then
    FCount:=v
  else
    FCount:=0
end;
 
function TOne.GetCount:Integer;
begin
  Result:=FCount
end;
 
function TOne.ToString:string;
var
  i:Integer;
begin
  Result:='';
  if FCount=0 then
    Exit;
  for i:=1 to FCount do
    Result:=Result+'1'
end;
 
procedure TOne.SetCountFromStr(v:String);
var
  i:Integer;
begin
  FCount:=0;
  if length(v)=0 then
    Exit;
  for i:=1 to length(v) do
    if v[i]='1' then
      inc(FCount)
end;
 
constructor TOne.Create;
begin
  FCount:=0;
end;
Если вы где-то в коде напишете, например
Delphi
1
2
One1.Count:=15;
Edit1.Text:=One1.AsString;
вместо него выполнится
Delphi
1
2
One1.SetCount(15);
Edit1.SetText(One1.ToString);//TEdit.Text - тоже свойство
Добавлено через 15 минут
Свойства также могут работать напрямую с переменными, то есть можно было бы написать так:
Delphi
1
property Count:Integer read FCount write SetCount;
1
10.01.2012, 17:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.01.2012, 17:22
Помогаю со студенческими работами здесь

Может ли функция быть действительной частью
U=x^2+y^2-xy \frac{dU}{dx}=\frac{dV}{dy}=2x-y\rightarrow V=\int(2x-y)dy=2xy-\frac{y^2}{2}...

Функция определяющая может ли быть построен треугольник
Всем привет! Помогите плиз с задачей, нужно создать функцию которая определяет может ли быть...

Может ли функция (процедура) быть полем record?
Всем доброго времени суток! Вопрос был объявлен в заголовке:может ли процедура(функция) быть полем...

Может ли быть функция кондиционера в тепловой завесе?
Модель Arvin RM-1209S-D/Y. Продавец сообщает, что есть такая функция.И вообще как модель в целом?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru