コンパイラ属性
属性(RTTI) への移動
一部の特殊な属性により、Delphi コンパイラ の特定の機能が発生します。
Ref
Ref
属性は、関数に(値ではなく)参照で渡されるように定数の関数パラメータを修飾するために使用されます。詳細については、「定数パラメータ」を参照してください。
volatile
volatile
属性は、別のスレッドにより変更される可能性があるフィールドにマークを付けて、そのフィールドの値をレジスタまたは別の一時メモリ領域にコピーする操作がコード生成の際に最適化されないようにするために使用されます。
volatile
属性を使用して、次の宣言にマークを付けることができます:
volatile
属性を使用して、次の宣言にマークを付けることはできません:
type
TMyClass = class
private
[volatile] FMyVariable: TMyType;
end;
属性 Weak と Unsafe
Weak
Weak はインターフェイス参照で、参照するオブジェクトの参照カウントは増加させません。これは [weak] 修飾子でマーク付けされます。この機能は、Delphi でのみサポートされていません。 weak 参照は、次の場合で使用できます:
-
- 参照カウントの増加を避けるため
- インターフェイスの参照を管理するため。つまり、システムが、実オブジェクトが削除された際に、それらをトラッキングします。
- メモ: weak 参照は完全に管理されるため、参照されたオブジェクトが破壊されると、自動的に nil が設定されます。
-
- クロス参照による、2 つのオブジェクト間での循環参照を壊すため。これが発生すると、メモリ リークが発生してしまいます。
例として、同じ型の別のインターフェイスへの参照を受け取る、次のようなインターフェイスと、それを実装する内部参照を 1 つ持ったクラスを考えてみましょう。
type
ISimpleInterface = interface
procedure DoSomething;
procedure AddObjectRef(Simple: ISimpleInterface);
end;
TObjectOne = class(TInterfacedObject, ISimpleInterface)
private
AnotherObj: ISimpleInterface;
public
procedure DoSomething;
procedure AddObjectRef(Simple: ISimpleInterface);
end;
2 つのオブジェクトとそれらのクロス参照を作成した場合、メモリ リークとなります:
var
One, Two: ISimpleInterface;
begin
One := TObjectOne.Create;
Two := TObjectOne.Create;
One.AddObjectRef(Two);
Two.AddObjectRef(One);
現在、Delphi では、private フィールド AnotherObj を、weak インターフェイス参照としてマーク付けすることで、これに対応できます:
[weak] AnotherObj: ISimpleInterface;
この変更により、AddObjectRef 呼び出しでオブジェクトをパラメータとして渡しても、参照カウントは変わらず 1 のままであり、その変数がスコープの外にでると 0 に戻り、オブジェクトはメモリから解放されます。
Unsafe
Unsafe 参照 はインターフェイス参照で、参照するオブジェクトの参照カウントは増加させません。 これは [unsafe] 修飾子でマーク付けされます。
参照の合計カウントから除外されるインターフェイス参照を作成する場合に、unsafe を使うことができます。例:
procedure TForm3.Button2Click(Sender: TObject);
var
[unsafe] OneIntf: ISimpleInterface;
begin
OneIntf := TObjectOne.Create;
OneIntf.DoSomething;
end;
関連項目
- volatile(C++)