Могу ли я перегрузить операторы для своих классов в Delphi? - PullRequest
1 голос
/ 01 декабря 2008

Я столкнулся с небольшой проблемой - я не знаю, смогу ли я определить свои собственные операторы для своих классов. Например:

type
  TMinMatrix = class(TMatrix)
    private
      RowAmount: Byte;
      ColAmount: Byte;
      Data: DataMatrix;
      DemVector, SupVector: SupplyDemand;
    public
      constructor Create(Rows, Cols: Byte);
      function GetRowAmount: Byte; override;
      function GetColAmount: Byte; override;
      destructor Destroy;
  end;

Как я могу - или не могу :) - сделать что-то вроде:

TMinMatrix TMinMatrix::operator=(TMinMatrix* matr)    (c++ code)

И, кстати, я могу определить конструктор копирования для моего класса?

Ответы [ 8 ]

5 голосов
/ 01 декабря 2008

Delphi Win32 2007 и 2009 поддерживает перегрузку операторов класса только для записей, вы можете иметь неявные и явные операторы. Delphi .Net поддерживает операторы классов для записей и классов.

3 голосов
/ 01 декабря 2008

Операторская перегрузка возможна в версиях Delphi .NET, более старые версии Delphi не поддерживают ее.

2 голосов
/ 06 сентября 2009
type
  TMinMatrix = class(TMatrix)
    public
      A : integer;
      class operator Add( ATM, BTM : TMinMatrix ) : TMinMatrix;
          // CTM := ATM + BTM
      class operator Subtract( ATM, BTM : TMinMatrix ) : TMinMatrix;
          // CTM := ATM - BTM;
    end;

class operator TMinMatrix.Add( ATM, BTM : TMinMatrix ) : TMinMatrix;
  begin
    result := ATM.A + BTM.A;
  end;

class operator TMinMatrix.Subtract( ATM, BTM : TMinMatrix ) : TMinMatrix;
  begin
    result := ATM.A - BTM.A;
  end;


var
  A, B, C : TMinMatrix;
begin
  C := A + B;  // calls Add()
  C := B - A;  // calls Subtract()
end.

Другие операторы:

Add        Binary   Add(a: type; b: type): resultType;         +   
Subtract   Binary   Subtract(a: type; b: type) : resultType;   -   
Multiply   Binary   Multiply(a: type; b: type) : resultType;   *   
Divide     Binary   Divide(a: type; b: type) : resultType;     /
IntDivide  Binary   IntDivide(a: type; b: type): resultType;   div   
Modulus    Binary   Modulus(a: type; b: type): resultType;     mod   
LeftShift  Binary   LeftShift(a: type; b: type): resultType;   shl   
RightShift Binary   RightShift(a: type; b: type): resultType;  shr   
LogicalAnd Binary   LogicalAnd(a: type; b: type): resultType;  and   
LogicalOr  Binary   LogicalOr(a: type; b: type): resultType;   or   
LogicalXor Binary   LogicalXor(a: type; b: type): resultType;  xor   
BitwiseAnd Binary   BitwiseAnd(a: type; b: type): resultType;  and   
BitwiseOr  Binary   BitwiseOr(a: type; b: type): resultType;   or   
BitwiseXor Binary   BitwiseXor(a: type; b: type): resultType;  xor   

;)

2 голосов
/ 01 декабря 2008

«Традиционный» метод копирования классов в Delphi заключается в переопределении метода «AssignTo» в TPersistant. Это обычно принимает форму

TSubclass(Dest).Field1 := Field1;
TSubclass(Dest).Field2 := Field2;

Что немного боли.

конструктор CreateCopy будет вызывать этот метод:

constructor CreateCopy(ASource : TMyClass);
begin
  Create;
  Assign(ASource); // calls AssignTo
end;

Еще одна хитрость в более поздних (работавших в 2006 г.) версиях Delphi - использовать тип записи для хранения полей.

class TMyClass = class(TPersistent)
protected
  type  // 2005+ only, otherwise use standalone record
    TMyRecord = record
    Name : string;
    ID : integer;
  end;

  FData : TMyRecord;
  procedure AssignTo(Dest : TPersistent);override;
public
  property Name : string read FData.Name;
  property ID: Integer read FData.ID;
end;

procedure TMyClass.AssignTo(Dest : TPersistent);
begin
  if Dest is TMyClass then
     TMyClass(Dest).FData := FData
  else
    inherited; // raise EConvertError
end;

Это усложняется, если вы продолжаете добавлять поля в подклассы - нужно добавлять новые типы записей, но оно автоматически обрабатывает новые поля, добавленные в TMyrecord (не нужно забывать обновлять AssignTo ())

1 голос
/ 06 сентября 2009

Перегрузка операторов в Delphi Win32 работает только для записей, а не для классов.

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

Я дал сеанс по перегрузке оператора записи в CodeRage 3; Вы можете получить слайды и пример кода на 26326 CR3: обнуляемые типы с записями, методами и перегрузкой операторов и / или посмотреть воспроизведение видео на СКАЧАТЬ ВИДЕО РЕПЛЕЙ .

Это было резюме сессии:

Обнуляемые типы с записями, методы и оператор перегружен одним из вещи, где данные из баз данных и Делфи нативные типы отличаются, это поддержка NULL. Когда вы работаете с базы данных много в Delphi, вы хотите иметь тип данных, который поддерживает NULL. В В прошлом вы должны были использовать варианты, но уже нет! С введением перегрузка оператора, вы можете сделать это с типами записей тоже. Эта сессия показывает, как.

Причина, по которой перегрузка оператора возможна только для записей в Delphi Win32 (т.е. не .NET), заключается в том, что записи являются типами значений, поэтому их управление памятью не является динамическим. Классы являются ссылочными типами, поэтому требуют динамического выделения памяти: им требуется концепция сборщика мусора, чтобы операторы могли с ними работать.

Поскольку в Delphi Win32 отсутствует концепция сборщика мусора, невозможно иметь операторы для классов в Delphi Win32.

Обратите внимание, что CodeRage 4 начинается на следующей неделе. У этого есть хороший ряд спикеров и сессий.

1 голос
/ 01 декабря 2008

Что бы ни говорили Дрейц и Сезар, + Delphi Win32 2007 и 2009, насколько я знаю, не поддерживают конструкторы копирования (я на 100% уверен в D2007, не совсем уверен в D2009).

0 голосов
/ 17 марта 2010

Delphi позволяет некоторым функциям или операторам перегружаться в объявлениях записей. Вы можете увидеть здесь: http://edn.embarcadero.com/article/34324

0 голосов
/ 01 декабря 2008

Полагаю, конструктор копирования - это идиома, а не языковая особенность.
Так что я могу сделать это так:
конструктор CreateCopy (var t: MyType);

конструктор MyType.CreateCopy (var t: MyType);
начать
//...
конец;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...