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

Вниз

Наследование и виртуальные функции   Найти похожие ветки 

 
nastya   (2005-09-22 15:15) [0]

Привет! Киньте, пожалуйста, идею, где и как поискать ошибку. Я иссякла:(
Есть два класса TAnyDevice и его наследник TThisDevice. Общие функции TAnyDevice , конкретика у TThisDevice.
Есть две задачи прочитать и записать серийный номер. Чтение происходит нормально, а при записи Acsess Violation. На мой взгляд объявления и порядок выполнения для чтения и записи аналогичен. Но почему тогда ошибка только при записи??!! Вот объявления:

TAnyDevice
//запись данных в память
function WriteDataToEEprom(Addr:integer;   Data:PByteArray;DataLen:word):boolean;
//чтение данных из памяти
function ReadDataFromEEprom(Addr:integer; var PData:PByteArray;DataLen:word):boolean;

//запись серийн. ном. в устройство открывая/закр. сеанс связи
function WriteSerialNumberOpenClose:boolean;virtual;
//чтение серийн. ном. из устройства открывая/закр. сеанс связи
function ReadSerialNumberOpenClose:boolean;virtual;

function WriteSerialNumber:boolean;virtual;
function ReadSerialNumber:boolean; virtual;
//чтение одного байта
function ReadByteFromEEprom(Addr:integer;var b:byte):boolean;virtual;abstract;
//запись одного байта
function WriteByteToEEprom(Addr:integer; b:byte):boolean;virtual;abstract;

TThisDevice
function ReadSerialNumber:boolean; override;
function WriteSerialNumber:boolean;override;
function ReadByteFromEEprom(Addr:integer;var b:byte):boolean;override;
function WriteByteToEEprom(Addr:integer; b:byte):boolean;override;

Порядок выолнения чтения
TAnyDevice .ReadSerialNumberOpenClose
TThisDevice.ReadSerialNumber
TAnyDevice .ReadDataFromEEprom
TThisDevice.ReadByteFromEEprom

Запись
TAnyDevice .WriteSerialNumberOpenClose
TThisDevice.WriteSerialNumber
TAnyDevice.WriteDataFromEEprom
TThisDevice.WriteByteFromEEprom<<--!!!! здесь баг

в теле TAnyDevice.WriteDataFromEEprom при попытке вызвать
WriteDataFromEEprom Access Violation.


 
umbra ©   (2005-09-22 15:30) [1]

Из хелпа про абстрактные методы:

You can call an abstract method only in a class or instance of a class in which the method has been overridden.

Т.е. их можно вызывать только в классе-наследнике,где они реализованы. В TAnyDevice WriteByteFromEEprom вызывать нельзя


 
Digitman ©   (2005-09-22 15:30) [2]


> TAnyDevice.WriteDataFromEEprom
> TThisDevice.WriteByteFromEEprom<<--!!!! здесь баг


ЗАЧЕМ ДВАЖДЫ вызывать метод WriteByteFromEEprom() ОДНОГО И ТОГО ЖЕ объекта ?

ведь поскольку этот метод у класса-предка является виртуальным и он перекрыт в классе-потомке, то при первый же вызов - это  вызов метода  TThisDevice.WriteByteFromEEprom !

?


 
Arm79 ©   (2005-09-22 15:30) [3]

а все таки исходники то не мешало бы...


 
nastya   (2005-09-22 15:34) [4]

[2]
так я дважы и не вызызваю
в теле TAnyDevice.WriteDataToEEprom по количеству байт вызывается
WriteByteToEEprom перекрытый в классе TThisDevice


 
nastya   (2005-09-22 15:37) [5]

[1]

> Т.е. их можно вызывать только в классе-наследнике,где они
> реализованы. В TAnyDevice WriteByteFromEEprom вызывать нельзя

А как еще тогда?
Идеология записи мноджества байт общая -пишем их по одному в цикле. То есть это метод уровня TAnyDevice. А как конкретно этот байт закинуть знает только реальное устройство.


 
Digitman ©   (2005-09-22 15:38) [6]


> так я дважы и не вызызваю


здрасть-приехали !

а ЭТО что  ?

TAnyDevice.WriteDataFromEEprom
TThisDevice.WriteByteFromEEprom<<--!!!! здесь баг

используется один и тот же, судя по всему, объект..


 
umbra ©   (2005-09-22 15:40) [7]


> в теле TAnyDevice.WriteDataToEEprom по количеству байт вызывается
> WriteByteToEEprom перекрытый в классе TThisDevice


Так вызывается ж в том классе, где он абстрактный! Его там как бы и нет вовсе, название одно! А можно его вызывать только там, где он перекрыт, т.е в TThisDevice, да и то это будет не TAnyDevice.WriteByteToEEprom, а TThisDevice.WriteByteToEEprom, о котором TAnyDevice ничего не знает.


 
Digitman ©   (2005-09-22 15:41) [8]


> nastya


приводи уже РЕАЛЬНЫЙ код ... иначе - базар-вокзал ...


 
nastya   (2005-09-22 15:43) [9]

[6]
Торможу?? :)

function  TAnyDevice.WriteDataToEEprom(Addr:integer; PData:PByteArray;DataLen:word):boolean;
var
i,a:integer;
b:word;
Begin
result:=true;
b:=0;
if DataLen<=0 then
 exit;
repeat
 a:=Addr+b;
 result:=result and WriteByteToEEprom(a,PData[b]);
 b:=b+1;
until (not result) or (b>DataLen-1);
End;


 
Digitman ©   (2005-09-22 15:49) [10]

э-э-э .. скорей я торможу) ...

тогда объясни мне, тундре, накой ляд ты сначала вызываешь Предок.WriteDataToEEprom, а следом Наследник.WriteByteToEEprom, если Предок при исполнении перекрытого в Наследнике WriteDataToEEprom и так уже вызывает тот самый WriteByteToEEprom ?


 
nastya   (2005-09-22 15:50) [11]

[7]
так реальный - то объект TThisDevice


 
umbra ©   (2005-09-22 15:55) [12]

А вы этот метод сделайте не абстрактным, а просто виртуальным, а в имплементации пусть он будет пустой или просто возвращает true


 
nastya   (2005-09-22 16:00) [13]

[10]
Еще раз. Сначала.

1)Device:=TThisDevice.Create

2)Device.WriteSerialNumberOpenClose (реально этот метод в TAnyDevice)
   function TAnyMeter.WriteSerialNumberOpenClose:boolean;
     Begin
       result:=false;
       if not HardOpenSession then exit;
       result:=WriteSerialNumber; //Здесь переопределено в TThisDevice
      CloseSession;
     End;

function  TThisDevice.WriteSerialNumber:boolean;
   var
    Dat:array[1..128] of byte;
    Addr:word;
    Len:byte;
 Begin
    result:=false;
   здесь готовлю данные
   if not WriteDataToEEprom(Addr,@Dat[1],Len) then //здесь реально TAnyDevice
    begin
         обработка ошибки  
        exit;
    end;
    result:=true;
  End;


 
nastya   (2005-09-22 16:03) [14]

[13] попробую
просто на мой взгляд все должно работать нормально и так, то есть если я правильно понимаю, абстрактиные методы примерно для такого использования и преднозначены :)


 
Digitman ©   (2005-09-22 16:13) [15]

так...
базар по поводу виртуальности/абстрактности/наследования м.б. долгим и бесплодным - книга даст ВМСЕ ответы, ибо она - источник знаний.

поехали назад, к отправной точке сабжа, обладающей НЕОПОРОВЕРЖИМЫМИ конкретностями

цитирую :


> а при записи Acsess Violation


приведи дословно сообщение об исключении, конкретную строчку кода конкретного метода конкретного класса, при выполнении которой было возбуждено данное исключение


 
nastya   (2005-09-22 16:13) [16]

[13]
TAnyMeter=TAnyDevice -это я для простоты :)


 
umbra ©   (2005-09-22 16:13) [17]


> umbra


> пусть он будет пустой


прошу прощения, не надо делать пустым. это ж функция


 
nastya   (2005-09-22 16:24) [18]

[15]

function  TAnyDevice.WriteDataToEEprom(Addr:integer; PData:PByteArray;DataLen:word):boolean;
var
  i,a:integer;
  b:word;
Begin
 result:=true;
 b:=0;
 if DataLen<=0 then
   exit;
 repeat
   a:=Addr+b;
   result:=result and WriteByteToEEprom(a,PData[b]);
   b:=b+1;
until (not result) or (b>DataLen-1);
End;

Выдает:
Project.... raised exception EAccessViolation with message "Access violation at adress 00481F13 in module... Read of adress 0000001C".

Причем выдает при пошаговой отладке именно в этот момент -при попытке выполнить WriteByteToEEprom. Для отладки же пыталась строчкой раньше посмотреть self.ClassName - накрывается тогда здесь.


 
nastya   (2005-09-22 16:25) [19]

[17] ну это понятно


 
nastya   (2005-09-22 16:29) [20]

Я даже не прошу, мне помогать реально найти ошибку, но КАК хотя-бы ее искать??


 
Digitman ©   (2005-09-22 16:31) [21]


> nastya   (22.09.05 16:29) [20]


> КАК хотя-бы ее искать?


именно ТАК и искать !

отправной точкой является локализованная тобой (в ходе пошаговой трассировки) трочка твоего кода, при выполнении которой возникает проблемная ситуация.

ты эту строчку локализовала ?

нет.

вот этим и займись !


 
nastya   (2005-09-22 16:34) [22]

[21]
Понятно, что проблема с памятью где-то не здесь. Здесь только результат. А как найти место реальной ошибки...


 
umbra ©   (2005-09-22 16:37) [23]


> А как найти место реальной ошибки...


> function WriteByteToEEprom(Addr:integer; b:byte):boolean; virtual; abstract;
>


 
Digitman ©   (2005-09-22 16:41) [24]


> как найти место реальной ошибки


трасс ируя пошагово код своей программы ... где F7 жмакнешь, а где F8 - по ситуации ... главное - ЛОКАЛИЗОВАТЬ "атомарный" вызов, т.е. тот вызов , происходящее в теле которого уже вне сферы твоей компетенции, например, вызов WinAPI-ф-ции


 
nastya   (2005-09-22 16:49) [25]

[24]
так в этом месте все и накрывается, я же писала[18]

result:=result and WriteByteToEEprom(a,PData[b]);


 
Digitman ©   (2005-09-22 16:58) [26]


> nastya   (22.09.05 16:49) [25]


ну а ПОШАГОВО-то пройти тело вызываемого при этом мсетода TThisDevice.WriteByteToEEprom в голову разве не пришло ?!

кто ж тебя заставляет на этой строчке жмакать именно F8 ?

жмакай F7  - и поехали !
шаг за шагом в теле того самого метода, который является перекрытием абстрактного метода TAnyDevice.WriteByteToEEprom ..


> Access violation at adress 00481F13 in module.


меню Search -> Find Error...

вводишь там 00481F13 - дебагер покажет тебе строчку в твоем проекте, где данная проблема имеет тебя)


 
nastya   (2005-09-22 17:02) [27]

[26]
Оно накрывается при ПОПЫТКЕ вызова WriteByteToEEprom ! Разумеется я бы просмотрела.


 
Digitman ©   (2005-09-22 17:05) [28]

кто "оно" ? конкретно ?

WriteByteToEEprom у тебя - НЕ атомарная ф-ция !

она имеет ТВОЮ СОБСТВЕННУЮ реализацию !

состоящую из собственноручно тобой написанных операторов !

так вот я и спрашиваю - на КАКОМ из операторов, находящихся в теле реализованного тобой метода TThisDevice.WriteByteToEEprom, происходит сабж ?!


 
nastya   (2005-09-22 17:07) [29]

[28]
result:=result and WriteByteToEEprom(a,PData[b]);

При нажатии F7 для выполнения ЭТОЙ строки выдается Access Violation.
Не успевает зайти ВНУТРЬ тела.


 
Digitman ©   (2005-09-22 17:10) [30]

тогда поехали разбираться с фактическими параметрами ... что, как, где объявлено, как инициализировано и т.д. и т.п. ..


 
Digitman ©   (2005-09-22 17:12) [31]

ПЕРВОЕ, что тебе д.было прийти в голову - это средствами Evaluate/Modify просмотреть, а что же все-таки ФАКТИЧЕСКИ ты пытаешься передать параметрами a и PData[b]


 
nastya   (2005-09-22 17:20) [32]

[31] Вот! Спасибо! Разумеется смотрела раньше, но сейчас со злости глянула внимательнее. И нашла :))


 
Digitman ©   (2005-09-22 17:24) [33]


> nastya   (22.09.05 17:20) [32]


> со злости глянула


вот видишь !)

иной раз злость (на самою себя или на свою недогадливость) - весьма полезное состояние души !

)


 
nastya   (2005-09-22 17:26) [34]

Не, злость была на Вас, что типа я такая недогадливая   и  элементарных вещей не сделала :)))


 
Digitman ©   (2005-09-22 17:29) [35]

понимаю)

но они действительно элементарные !

и мной изначально таки подразумевалось, что уж здесь-то дилетантского прокола с Вашей стороны как бы и не подразумевается)


 
nastya   (2005-09-22 17:32) [36]

Так я все и сделала .... вроде бы
Ладно, в следующий раз буду внимательнее. Спасибо


 
Digitman ©   (2005-09-22 17:32) [37]


> nastya   (22.09.05 17:26) [34]


согласиь, все же встр.отладчик  - могучая штука ?

и СВОБОДНОЕ ПРАКТИЧЕСКОЕ владение им (и многими основными его фичами) намного ускоряет ход отладки ?)


 
nastya   (2005-09-22 17:35) [38]

Только он иногда глючит. Реально с этим сталкивалась. Поэтому, вместо того, чтобы еще раз просмтотреть, начинаю копать глубже.


 
Digitman ©   (2005-09-22 17:47) [39]


> nastya   (22.09.05 17:35) [38]


> он иногда гл


врешь ведь)

НЕпонимание тобой работы дебагера в конкретных ситуациях НЕ означает его "глючность" в принципе.



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

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

Наверх





Память: 0.55 MB
Время: 0.038 c
1-1127384055
john_mag
2005-09-22 14:14
2005.10.16
TDBGrid


3-1125987508
Shopot
2005-09-06 10:18
2005.10.16
Главная и подчиненная таблицы.


2-1127134150
Fantasy
2005-09-19 16:49
2005.10.16
Сервис HELP


14-1127393573
Андрей Жук
2005-09-22 16:52
2005.10.16
Шо творится...


3-1125544025
Ярослав
2005-09-01 07:07
2005.10.16
Определить изменилась ли запись в триггере?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский