Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Наследование и виртуальные функции [D5]


Страницы:   1 2

nastya ©   (2005-09-22 15:15:00) 

Привет! Киньте, пожалуйста, идею, где и как поискать ошибку. Я иссякла:(
Есть два класса 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.


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

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


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

[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 - накрывается тогда здесь.


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


> umbra


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


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


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

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


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

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

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

цитирую :


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


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


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

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


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

[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;


umbra   (2005-09-22 15:55:00) [28]

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


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

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


Digitman   (2005-09-22 15:49:00) [30]

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

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


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

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

function  TAnyDevice.Write DataToEEprom(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 Write ByteToEEprom(a,PData[b]);
 b:=b+1;
until (not result) or (b>DataLen-1);
End;


Digitman   (2005-09-22 15:41:00) [32]


> nastya


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


umbra   (2005-09-22 15:40:00) [33]


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


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


Digitman   (2005-09-22 15:38:00) [34]


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


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

а ЭТО что  ?

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

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


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

[1]

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

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


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

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


umbra   (2005-09-22 15:30:00) [37]

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

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

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


Arm79   (2005-09-22 15:30:00) [38]

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


Digitman   (2005-09-22 15:30:00) [39]


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


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

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

?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо