2011-12-27 5 views
2

iは、オペレータのオーバーロードでの作業、私はこのような状況を持っている、側FRA:F2047循環ユニット基準

unit _TIns; 

interface 

uses 
    _TExtract; 

type 
    TIns = record 
    private type 
    TInsArray = array [1..90] of Boolean; 
    var 
    FInsArray: TInsArray; 
    public 
    class operator Implicit(const Value: TExtract): TIns; 
    class operator Implicit(const Value: TIns): TExtract; 
    end; 

implementation 
    // Code 
end. 

と、他方の側から:もちろん

unit _TExtract; 

interface 

uses 
    _TIns; 

type 
    TExtract = record 
    private type 
    TExtractEnum = 1 .. 90; 
    var 
    FExtractEnum: TExtractEnum; 
    public 
    class operator Implicit(const Value: Integer): TExtract; 
    class operator Implicit(const Value: TExtract): Integer; 
    class operator In(A: TExtract; B: TIns) : Boolean; 
    end; 

implementation 
    // Code 
end. 

、私は理解していますどこが問題なのか、それは両方のユニットが他のものを呼び出すことです。しかし、それを解決するものとして理解していない。私が同じ単位でそれを定義しようとすると、最初のTExtractはTInを見つけられません。そうでなければTInsはTExtractを見つけません。 私は依存関係を削除して解決することができますが、存在しない場合にのみ解を解くことができますが、このデータ型を両方に使用します。 おかげさまで、ありがとうございました。

+0

[stackoverflowの] [1] [1]:のhttp://のstackoverflow。 com/questions/1284959/how-to-avoid-circular-unit-reference – PresleyDias

答えて

5

2つの循環参照の問題があります。まず、インタフェースセクションでそれぞれを参照する2つのユニットを宣言しています。それはいろいろな方法で解決することができます。今のところ私はその問題を無視し、他の循環参照問題に焦点を当てるつもりです。そうするために、私はすべてのコードが同じユニットにあると仮定するつもりです。

さらに循環参照の問題は、TInsTExtractを指し、逆もまた同様です。この特定の循環性を破るためには、クラスで一般的に行われているように、前方参照を導入する必要があります。しかし、recordタイプでは前方参照はできません。

クラス型の前方参照は可能ですが、クラス型とレコード型の間には基本的な違いがあります。レコードタイプは値タイプであり、クラスタイプは参照タイプです。現在のDelphiコンパイラの実装では、値型の前方参照はサポートされていません。

問題の解決策は、両方の型を参照する演算子を最後に宣言されたレコードに移動することです。たとえば:

TIns = record 
private type 
    TInsArray = array [1..90] of Boolean; 
var 
    FInsArray: TInsArray; 
end; 

TExtract = record 
private type 
    TExtractEnum = 1 .. 90; 
var 
    FExtractEnum: TExtractEnum; 
public 
    class operator Implicit(const Value: TExtract): TIns; 
    class operator Implicit(const Value: TIns): TExtract; 
    class operator Implicit(const Value: Integer): TExtract; 
    class operator Implicit(const Value: TExtract): Integer; 
    class operator In(A: TExtract; B: TIns) : Boolean; 
end; 

次の2つの別々のユニットを保持したい場合は、このようにそれを実行します。

  1. はユニット_TInsTInsを入れてください。
  2. do _TExtract_TInsからです。
  3. TExtractをユニット_TExtractに置きます。
  4. _TExtractのインターフェイスセクションから_TInsを使用してください。このよう

:これは役立つかもしれ

unit _TIns; 

interface 

type 
    TIns = record 
    private type 
    TInsArray = array [1..90] of Boolean; 
    var 
    FInsArray: TInsArray; 
    end; 

implementation 

end. 

 

unit _TExtract; 

interface 

uses 
    _TIns; 

type 
    TExtract = record 
    private type 
    TExtractEnum = 1 .. 90; 
    var 
    FExtractEnum: TExtractEnum; 
    public 
    class operator Implicit(const Value: TExtract): TIns; 
    class operator Implicit(const Value: TIns): TExtract; 
    class operator Implicit(const Value: Integer): TExtract; 
    class operator Implicit(const Value: TExtract): Integer; 
    class operator In(A: TExtract; B: TIns) : Boolean; 
    end; 

implementation 
    // Code 
end. 
+0

理解して、_TExtractを実装して_TExtractを呼び出すのではなく、_TExtract実装のコードを_TIns実装にコピーする必要があります。さて、ありがとう。 –

+0

問題の解決策が何であるかを覚えておいて答えに加えました。 –

+0

問題は、両方のオペレータがotherを呼び出すことです。だから私は両方のためにそれを行う必要がありますので、コールユニット、正しい? –