6

以下に 2 つの単純なクラスを示します。最初はどちらもキーワード (virtual、overload、override、reintroduce) を持っていません。

TComputer = class(TObject)
public
   constructor Create(Teapot: Integer);
end;

TCellPhone = class(TComputer)
public
   constructor Create(Teapot: Integer; Handle: string);
end;

上記の定義を少し短いものとして表します。

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);

また、構築時には、コンストラクター ( , )TCellPhoneが 1 つしかありません。これは、祖先コンストラクターが非表示になっているためです。i の可視コンストラクターを次のように示します。intstringTCellPhone

  • ティーポット: 整数; ハンドル:紐

ここで質問ですが、最初の 3 つのケースは理にかなっていますが、4 番目のケースは意味がありません。

1. 祖先コンストラクターは子孫によって隠されています。

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);
  • Teapot: Integer; Handle: string

これは理にかなっています。新しいコンストラクターを宣言したため、祖先コンストラクターは非表示になっています。

2. 祖先の仮想コンストラクターは子孫によって隠されています。

TComputer = class(TObject)
   constructor Create(Teapot: Integer); virtual;

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string);
  • Teapot: Integer; Handle: string

これは理にかなっています。新しいコンストラクターを宣言したため、祖先コンストラクターは非表示になっています。

注:先祖は仮想であるため、Delphi は、仮想先祖を非表示にしていることを警告します (前の静的コンストラクターを非表示にする例: 誰も気にしないので、警告はありません)。reintroduceを追加することで、警告を抑制することができます (「ええええええ、私は仮想コンストラクターを隠しています。そう するつもりでした」という意味です)。

    TComputer = class(TObject)
       constructor Create(Teapot: Integer); virtual;

    TCellPhone = class(TComputer)
       constructor Create(Teapot: Integer; Handle: string); reintroduce;

3. オーバーロードのため、祖先コンストラクターが子孫に隠されていません:

TComputer = class(TObject)
   constructor Create(Teapot: Integer);

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string); overload;
  • Teapot: Integer; Handle: string
  • Teapot: Integer

子孫コンストラクターは祖先のオーバーロードであるため、これは理にかなっています。そのため、両方を存在させることができます。祖先コンストラクターは隠されていません。

4. オーバーロードのため、仮想先祖コンストラクターが子孫に隠されていません -それでも警告が表示されます:

これは意味をなさないケースです:

TComputer = class(TObject)
   constructor Create(Teapot: Integer); virtual;

TCellPhone = class(TComputer)
   constructor Create(Teapot: Integer; Handle: string); overload;
  • Teapot: Integer; Handle: string
  • Teapot: Integer

    メソッド 'Create' は、基本型 'TComputer' の仮想メソッドを非表示にします

これはほとんど意味がありません。先祖が隠れていないだけでなく、子孫が過負荷になっています。文句を言うべきでもありません

何を与える?

4

3 に答える 3

5

Delphi のドキュメントには次のように書かれています。

仮想メソッドをオーバーロードする場合は、子孫クラスで再宣言するときに reintroduce ディレクティブを使用します。例えば、

type
  T1 = class(TObject)
    procedure Test(I: Integer); overload; virtual;
  end;
  T2 = class(T1)
    procedure Test(S: string); reintroduce; overload;
  end;

お気づきのように、reintroduce ディレクティブがなくても機能しますが、警告が表示されます。

また、実際には TObject.Create を非表示にしていますが、警告とは関係ありません。TObject.Create にもアクセスしたい場合は、次のようにします。

type
  TComputer = class(TObject)
    constructor Create(Teapot: Integer); reintroduce; overload; virtual;
  end;

type
  TCellPhone = class(TComputer)
    constructor Create(Teapot: Integer; Handle: String); reintroduce; overload;
  end;
于 2010-10-08T20:03:38.383 に答える
2

私はトリニダードに同意します。警告の背後にあるロジックは、おそらく祖先メソッドが仮想/動的であるかどうか、および子孫メソッドがオーバーライドまたは再導入としてマークされているかどうかのみを調べます。

これは、「通常の」メソッドにも当てはまります。

reintroduce修飾子の前に配置するoverloadか、オーバーライドされたコンストラクターを祖先コンストラクターに単に委譲する子孫クラスに追加することで、これを抑制することができます。

于 2010-10-08T19:39:42.483 に答える
1

私はすでにそれに気付きました。継承されたメソッドが非表示になっていないため、私が知る限り、警告はバグです。まだ報告されていない場合は、qc.embarcadero.com で報告する必要があります。

于 2010-10-08T18:21:31.717 に答える