1


3

私は少し問題に直面しました - 私は私のクラスのために私自身の演算子を定義できるかどうかわかりません。 例えば:

タイプTMinMatrix = class(TMatrix)private RowAmount:バイト。 ColAmount:バイト。データ:DataMatrix。 DemVector、SupVector:SupplyDemand。パブリックコンストラクタCreate(Rows、Cols:Byte); function GetRowAmount:バイト。オーバーライド;関数GetColAmount:バイト。オーバーライド;デストラクタ終わり;

どのように私はできます - または私はできません:) - のような何かをする:

TMinMatrix TMinMatrix :: operator =(TMinMatrix * matr)(Cコード)

ところで、自分のクラスにコピーコンストラクタを定義することはできますか?

8 回答


5


Delphi Win32 2007および2009は、レコードに対するクラス演算子のオーバーロードのみをサポートしています。暗黙的および明示的な演算子を使用できます。 Delphi .NETは、レコードとクラスのクラス演算子をサポートしています。


3


演算子のオーバーロードはDelphi .NETバージョンでは可能ですが、古いバージョンのDelphiではサポートされていません。


2


Delphiでクラスをコピーする「伝統的な」方法は、TPersistantの「AssignTo」メソッドをオーバーライドすることです。 これは通常、

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

これは少し苦痛です。

CreateCopyコンストラクタはこのメソッドを呼び出します。

コンストラクタCreateCopy(ASource:TMyClass);作成を開始します。割り当て(ASource)。 // AssignTo endを呼び出します。

Delphiのそれ以降のバージョン(2006年に動作)のもう一つのトリックはフィールドを格納するためにレコードタイプを使うことです。

クラスTMyClass = class(TPersistent)保護された型// 2005のみ。それ以外の場合はスタンドアロンレコードを使用するTMyRecord = record Name:文字列。 ID:整数。終わり;

FData:TMyRecord;プロシージャAssignTo(Dest:TPersistent);オーバーライド。パブリックプロパティName:文字列FData.Nameを読み取ります。プロパティID:整数読み取りFData.ID。終わり;

TMyClass.AssignTo(Dest:TPersistent); DestがTMyClassであれば開始し、TMyClass(Dest)を指定します。.FData:= FDataそれ以外は継承されます。 // EConvertError endを送出します。

サブクラスにフィールドを追加し続けると面倒になります - 新しいレコードタイプを追加する必要がありますが、TMyrecordに追加された新しいフィールドを自動的に処理します(AssignTo()を更新することを忘れないでください)。


2


type TMinMatrix = class(TMatrix)public A:整数。クラス演算子Add(ATM、BTM:TMinMatrix):TMinMatrix; // CTM:= ATM BTMクラス演算子Subtract(ATM、BTM:TMinMatrix):TMinMatrix; // CTM:= ATM  -  BTM;終わり;

クラス演算子TMinMatrix.Add(ATM、BTM:TMinMatrix):TMinMatrix;開始結果:= ATM.A BTM.A;終わり;

クラス演算子TMinMatrix.Subtract(ATM、BTM:TMinMatrix):TMinMatrix;開始結果:= ATM.A  -  BTM.A;終わり;

var A、B、C:TMinMatrix。 C:= A Bを開始します。 // Add()C:= B  -  Aを呼び出します。 // Subtract()endを呼び出します。

他の演算子は以下のとおりです。

バイナリの追加Add(a:type; b:type):resultType;バイナリ減算減算(a:type; b:type):resultType; - 乗算バイナリ乗算(a:type; b:type):resultType; * 2進数の除算(a:type; b:type):resultType; / IntDivideバイナリIntDivide(a:type; b:type):resultType; divモジュラスバイナリモジュラス(a:type; b:type):resultType; mod LeftShiftバイナリLeftShift(a:type; b:type):resultType; shl RightShiftバイナリRightShift(a:type; b:type):resultType; shr LogicalAnd Binary LogicalAnd(a:タイプ; b:タイプ):resultType; LogicalOrバイナリLogicalOr(a:type; b:type):resultType;またはLogicalXor Binary LogicalXor(a:type; b:type):resultType。 xor BitwiseAndバイナリBitwiseAnd(a:type; b:type):resultType; BitwiseOrバイナリBitwiseOr(a:type; b:type):resultType;またはBitwiseXorバイナリBitwiseXor(a:type; b:type):resultType;またはxor

;)


1


DrejcとCesarがDelphi Win32 2007と2009が私の知る限りコピーコンストラクタをサポートしていないと言ったものは何でも(私はD2007では100%、D2009では完全にはわからない)。


1


Delphi Win32での演算子オーバーロードはレコードに対してのみ機能し、クラスに対しては機能しません。

これはDelphi 2006以降で動作しますが、Delphi 2007では修正が容易になるいくつかのバグがありました(演算子結果の呼び出し関数に関連しています)。

CodeRage 3のレコードオペレータオーバーロードに関するセッションを行いました。スライドとサンプルコードは、http://cc.embarcadero.com/Item/26326[26326 CR3:null許容型w /レコード、メソッドで入手できます。

これはセッションの要約です。

_ レコード、メソッド、および演算子のオーバーロードを持つNullable型データベースとDelphiネイティブ型のデータが異なる点の1つは、NULLのサポートです。 Delphiでデータベースを頻繁に扱う場合は、NULLをサポートするデータ型が必要です。 過去には、バリアントを使用しなければなりませんでしたが、それ以上は使用できません 演算子のオーバーロードが導入されたため、レコードタイプでもこれを実行できます。 このセッションではその方法を説明します。 _

オペレータによるオーバーロードの理由は、Delphi Win32のレコードに対してのみ可能です(つまり、 .NET以外の場合、レコードは値型なので、メモリ管理は動的ではありません。 クラスは参照型なので、動的なメモリ割り当てが必要です。演算子がそれらを処理するためには、ガベージコレクタの概念が必要です。

Delphi Win32ではガベージコレクタの概念がないため、Delphi Win32ではクラスの演算子を持つことはできません。

来週からhttp://conferences.embarcadero.com/coderage[CodeRage 4]が開始されます。 講演者やセッションが充実しています。


0


コピーコンストラクタは言語機能ではなくイディオムだと思います。 だから私はこのようにそれを行うことができます。コンストラクタCreateCopy(var t:MyType);

コンストラクタMyType.CreateCopy(var t:MyType);ベギン 終わり;


0


Delphiでは、レコード宣言内で特定の関数または演算子をオーバーロードすることができます。 あなたはここで見ることができます:http://edn.embarcadero.com/article/34324