Проблема с Delphi 2009 и типом объекта старого стиля - PullRequest
3 голосов
/ 18 июня 2009

У меня есть много старого кода, использующего тип объекта pascal старого стиля, который я пытаюсь заставить работать в Delphi 2009. Он компилируется, но, похоже, есть несколько проблем, связанных с виртуальными методами. Похоже, что об этой проблеме уже сообщалось в Quality Central:

http://qc.embarcadero.com/wc/qcmain.aspx?d=71723

Я надеялся, что кто-нибудь, кто все еще использует их (возможно, PatrickvL), сможет ответить более подробной информацией. У нас есть много кода, который использует объекты, и если это не будет исправлено, мы застряли. Заранее спасибо!

Ответы [ 4 ]

7 голосов
/ 18 июня 2009

Если вы используете виртуальные методы, то вы явно обращаетесь к объектам по ссылке, а не по значению. Именно так классы всегда работают в Delphi, поэтому переход на классы не должен быть слишком сложным.

Для любых типов объектов, которые не имеют виртуальные методы, вы сможете превратить их в записи. Записи могут теперь иметь методы, а также спецификаторы видимости. Однако наследование не поддерживается.

Объекты старого стиля устарели с 14 февраля 1994 года, даты выпуска первой версии Delphi. С тех пор они ухудшаются. Ты должен был отойти от них много лет назад.

3 голосов
/ 19 июня 2009

Хорошо. Сделано, я не могу заставить его выйти из строя ... Ваш D2009 полностью исправлен? Параметры проекта / компилятора?

Для полной уверенности и сравнения вот мои единицы:

--------------- Файл проекта

program testD2009;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Object1U in 'Object1U.pas',
  Object2U in 'Object2U.pas';


Var
  Object1 : PObject1;
  Object2 : PObject2;
begin
  try
    Object1 := New(PObject1,Init);
    Object1^.Add;
    Object1^.Deduct;

    Object2 := New(PObject2,Init);
    Object2^.Add;
    Object2^.Deduct;
    readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

-------------- Объект1, единица

unit Object1U;

interface

uses SysUtils;

Type
  PObject1 = ^TObject1;
  TObject1 = Object
    Magic: Array[0..3] of Byte;
    FCount     : Integer;
    Constructor Init;
    Procedure Add; virtual; { removing virtual allows the program to run }
    Procedure Deduct; virtual; { removing virtual allows the program to run }
    end;

implementation


Procedure TObject1.Add;
begin
  Writeln('Object1 Add');
end;

procedure TObject1.Deduct;
begin
  Writeln('Object1 Deduct');
end;

Constructor TObject1.Init;
begin
  inherited;
  FCount      := 0;
  Writeln('TObject1 Init');
end;

end.

---------------- Объект 2 ед.

unit Object2U;

interface

uses Object1U;

Type
  PObject2   = ^TObject2;
  TObject2   = Object(TObject1)
    Constructor Init;
    Procedure Add; virtual; { removing virtual allows the program to run }
    Procedure Deduct; virtual; { removing virtual allows the program to run }
   end;

implementation

procedure TObject2.Add;
begin
  Writeln('Object2 Add');
  inherited;
end;

procedure TObject2.Deduct;
begin
  Writeln('Object2 Deduct');
  inherited;
end;

Constructor TObject2.Init;
begin
  Inherited Init;
  fCount := 1;
  Writeln('TObject2:Init');
end;

end.

---------------- Вывод программы:

TObject1 Init
Object1 Add
Object1 Deduct
TObject1 Init
TObject2:Init
Object2 Add
Object1 Add
Object2 Deduct
Object1 Deduct

озадачен я:).

3 голосов
/ 19 июня 2009

Должен признать, что я выпил пару бутылок пива, просто для испытания :) Вам нужны магические байты. Согласно легенде, объекты старого стиля создают пространство для указателей, только если вы используете ЛЮБЫЕ виртуальные методы. Нет Виртуальных методов НЕТ VMT.

Указатель VMT ВСЕГДА ПЕРВЫЙ с новыми объектами стиля, потому что все они объявляют виртуальные методы. Кажется, кто-то забыл, что со старыми объектами стиля VMT может прийти позже. так что, предполагая, что это всего лишь один указатель, это заставляет его работать на моем D2009. Я не в духе компилятора, парень по имени Дэйв Джуэлл, который раньше писал для PC pro, мог бы подтвердить, что это будет стабильно ...

Type
  PObject1 = ^TObject1;
  TObject1 = Object
    Magic: Array[0..3] of Byte; //or integer or whatever I was playing with the size
    FCount     : Integer;
    Constructor Init;
    Procedure Add; virtual; 
    Procedure Deduct; virtual; 
    end;

Type
  PObject2   = ^TObject2;
  TObject2   = Object(TObject1)
    Constructor Init;
    end;

Тогда после строительства эти работы:

.
.
.
Object2^.Add;
Object2^.Deduct;

и я получаю соответствующий вывод на консоль

Я добавил дополнительный процесс, чтобы убедиться, что он работает на 2 виртуальных компьютерах:)

Между прочим, они работают независимо от того, поставили ли вы ^ или нет, 2009 знает, что вы имеете в виду: (

Отсутствие правильного исправления из embracodeland Вам все еще может потребоваться изменить определение каждого BASE-объекта. Надеюсь, вы могли бы сделать это с помощью поиска и вставки / замены или Grep ... Удачи.

2 голосов
/ 22 июня 2009

Я отправил электронное письмо нашим местным представителям Embarcadero по поводу этой проблемы и направил их в отчет по Quality Central. В основном они сказали нам переместить все объекты в классы, так что я предполагаю, что они не планируют исправлять это ... никогда. Я думаю, что мы в значительной степени согласились с тем, что мы должны идти по этому пути, если мы хотим двигаться вперед, поэтому сейчас нам просто нужно запланировать эту работу, прежде чем мы сможем перейти к обновлению до Delphi 2009.

Просто хотел поблагодарить всех, кто пытался помочь, но я считаю, что на данный момент это безнадежное дело: - (

...