5

私は Java 開発者で、最近 Delphi 開発者の帽子をかぶっています。

このような状況ではよくあることですが、「Java」の考え方を使用しながら Delphi で何かをしようとしてしまい、それらが機能しないと困惑します。

今日の問題は、インターフェイスの概念です。Java では、インターフェイスを定義していくつかのメソッドを与え、後でそのインターフェイスを実装するクラスを宣言できます。

私は Delphi で同じことをしようとしましたが、指を火傷しました。IInterface を拡張したインターフェイスを宣言しました。しかし、そのインターフェイスを実装する段階になると、宣言していないメソッド (QueryInterface、_AddRef、_Release) に対して多数の未実装メソッド エラーが発生しました。

ちょっとした Google から、TObject の代わりに TInterfacedObject を拡張する必要があると言われました。これは、サードパーティ クラスが最終的に TInterfacedObject を拡張しない限り、そのクラスに単純にインターフェイスを追加できないことを示唆しているため、私は不安でした。

しかし、インターフェイス オブジェクト .Free を設定するときが来たら、EInvalidPointer 例外が発生します。

その結果、Java 開発者や Delphi 開発者にとって、インターフェイスという言葉はまったく別のものを意味するという結論に達し始めています。

両方の言語に堪能な人が違いについて教えてくれますか?

乾杯。

4

2 に答える 2

8

Interface types in Delphi have three functions:

  1. Be a general language feature for abstracting interface from implementation a la interface types in Java.
  2. Form the core of Delphi's COM support (a Delphi IInterface is the same as the COM IUnknown).
  3. Provide a form of automated memory management in the context of a non-garbage collected environment.

These functions are conceptually distinct, and as you have found, produce a less than optimal result when combined in the same feature:

  • Every interface in Delphi must ultimately descend from IInterface/IUnknown, and as such, have the three IUnknown methods (AddRef, Release and QueryInterface - the first two are renamed _AddRef and _Release in Delphi to discourage you from calling them directly). If you want to be able to query for an interface at runtime, you also need to give it a GUID.
  • TInterfacedObject exists as a convenient base class, though you don't have to use it if you implement _AddRef, _Release and QueryInterface yourself (doing so involves a standard pattern, so it isn't hard). In principle, you can also disable reference counting by returning -1 for the first two (the TComponent class does this, for example).
  • Nonetheless, the compiler will always insert _AddRef and _Release calls when an object is accessed via an interface. This makes it frequently unsafe to access the same object through an object and interface reference even when _AddRef and _Release just return -1.
于 2013-09-30T18:03:54.873 に答える
3

違いはガベージコレクターにあります。Javaには1つあります。しかし、Delphi では、自分でオブジェクトを制御する必要があります。

_AddRef と _Release は、これを少し簡単にするために作成されました。変数がオブジェクトを指し始めると、Delphi は _AddRef を呼び出します。そこで、そのオブジェクトへの参照のカウンターを増やす必要があります。コード内の変数がオブジェクトへの「緩い」リンクの場合、Delphi は _Release を呼び出します。そこでカウンターを減らす必要があります。カウンターが 0 になると、このオブジェクトに対して destroy() を呼び出すことができますSelf.Destroy()

お役に立てれば。

PS。TInterfacedObject はこれらのメソッドをすでに実装しているため、Google と Delphi のドキュメントでは TInterfacedObject の使用を推奨しています。

于 2013-09-30T16:52:08.313 に答える