|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Несовместимость типов
Уважаемые форумчане.
Вот мой класс (заготовка). Класс будет работать с динамическим массивом Код:
unit U_Event; interface type TEvent = record F_1 : string; F_2 : integer; F_3 : string; end; type TEventList = class(TObject) private fCount: integer; fItemIndex: integer; function GetCount :integer; function SetCount(NewCount: integer): boolean; public items : array of TEvent; constructor Create; property Count : integer read GetCount Write SetCount; destructor free; virtual; end; implementation // Конструктор constructor TEventList.Create; begin inherited; fItemIndex := -1; fCount := 0; SetLength(items,fCount); end; // Изменение размеров массива событий function TEventList.SetCount(NewCount: integer): boolean; begin Result := True; if NewCount < 0 then begin Result := False; NewCount := 0; end; fCount := NewCount; SetLength(items,fCount); end; // Чтение размера массива событий function TEventList.GetCount: integer; begin result := fCount; end; // Разрушение объекта destructor TEventList.free; begin SetLength(items,0); Inherited Destroy; end; end. Ошибка в строке 23. Говорит о несовместимости типов. Скорее всего из-за того, что тип функции SetCount - Boolean а тип Count - integer. Как исправить ошибку, не меняя определения функции, или не получится? |
#2
|
||||
|
||||
Определил свойство Count как Integer, так будь добр соблюдать его.
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#3
|
|||
|
|||
То, что соответствие типов надо соблюдать, даже я знаю. Только вот в вызывающей программе хотелось бы иметь возможность написать:
Код:
List := TEventList.Create; .... .... .... if List.Coun(N) then ShowMessage('Размер массива изменён'), Последний раз редактировалось Alex55V, 04.03.2015 в 00:30. |
#4
|
|||
|
|||
В таком виде - никак.
Т.е. SetCount д.б. процедурой (не возвращать никаких значений). Если очень хочется отлавливать ошибку - выбрасывай исключение при ошибке изменения размера массива. Либо сделай само св-во только для чтения и public метод для изменения размера массива. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
Alex55V (04.03.2015)
|
#5
|
|||
|
|||
и деструктор не должен называться free !
free -это невиртуальная функция класса TObject, которая сама вызывает Destroy. поэтому нужно делать так Код:
type TEventList = class(TObject) .... destructor Destroy; virtual; end; Код:
destructor TEventList.Destroy; begin SetLength(items,0); Inherited Destroy; end; Код:
SetLength(items,0); Если в деструкторе больше кода не будет, то его можно совсем исключить. |
#6
|
|||
|
|||
Цитата:
Цитата:
Теперь просьбы Хотелось бы чтобы Ваши ответы были ни столь подробны. Лучше лишний раз переспрошу. Я могу путаться в понятиях и определениях. Огромная просьба поправляйте. Научите определять всю ли память освободила программа, после завершения своей работы |
#7
|
|||
|
|||
Цитата:
Цитата:
Цитата:
запример здесь - http://www.gunsmoker.ru/2009/04/freeandnil-free.html Которая вызывает TObject.Free, и затем обнуляет поданый ей указатель. А про Ваш free она ничего не знает и никогда его не вызовет. Про SetLength в деструкторе. В Delphi есть несколько категорий типов, которые имеют автоматическое время жизни. Это интерфейсы, строки, и всякие динамические массивы. При входе в процедуру/функцию, в которой есть переменные таких типов, или созданию объекта/структуры, в котором есть поля таких типов, они автоматически инициализируются nil-ом, что в случае строк и массивов эквивалентно массиву нулевой длины. И соответственно при выходе из процедуры/функции или уничтожению объекта/структуры, будут уничтожены и такие автоматические объекты. В Вашеи случае в объекте типа TEventList есть поле типа динамический массив, а в структуре TEvent ести два поля типа String. При разрушении TEventList автоматически будет вызван финализатор для поля items, который сначала проведёт финализацию всех своих элеиентов, при этом в каждом уничтожатся строки F_1 и F_3, а затем будет уничтожен сам массив. Но не забывайте, что наследники TObject не имеют автоматического время жизни, по этому все созданные руками объекты нужно уничтожать самому. |
Этот пользователь сказал Спасибо icWasya за это полезное сообщение: | ||
Alex55V (04.03.2015)
|
#8
|
|||
|
|||
icWasya у.
Спасибо за все Ваши разъяснения и ссылки. В связи с тем, что я пока чайник, и даже свисток имеется, то понял только общий смысл. Между прочим Вы ответили на вопросы, которые я хотел задать. |
#9
|
|||
|
|||
Цитата:
А зря. Собственно, можно было бы и так догадаться. Сеттер просто устанавливает значение аттрибуту (не путать со свойством) объекта. Там фунция просто не нужна, т.к. ей нечего возвращать. Если происходит ошибка, то надо просто выбрасывать исключение. А сообщение об ошибке в типе данных связвно с тем, как данный механизм реализован внутри языка. Фактически там объявлены процедурные типы для геттера и сеттера и если реальная процедура/фунция по сигнатуре (не кидаться помидорами, знаю. что там не сигнатура, но так понятнее для начинающего) не совпадает с указанным типом, то выдается сообщение о несоответствии типов. Последний раз редактировалось lmikle, 05.03.2015 в 06:44. |