最近、インディで同じ問題に遭遇しました。そのTIdStack
基本クラスには、その子孫 (など) がオーバーライドする独自の抽象メソッドでオーバーライドおよびオーバーロードする抽象メソッドとメソッドがありGetSocketOption()
ますSetSocketOption()
。これらのまったく同じ種類のコンパイラ エラーが発生していました。TIdStackBDSBase
TIdStackWindows
例えば:
type
TIdStack = class(TObject)
...
procedure GetSocketOption(ASocket: TIdStackSocketHandle;
ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption;
out AOptVal: Integer); virtual; abstract;
...
end;
.
type
TIdStackBSDBase = class(TIdStack)
...
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel;
AOptName: TIdSocketOption; out AOptVal: Integer); overload; override;
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel;
AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); overload; virtual; abstract;
...
end;
procedure TIdStackBSDBase.GetSocketOption(ASocket: TIdStackSocketHandle;
ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer);
var
LBuf, LLen: Integer;
begin
LLen := SizeOf(LBuf);
GetSocketOption(ASocket, ALevel, AOptName, LBuf, LLen);
AOptVal := LBuf;
end;
.
type
TIdStackWindows = class(TIdStackBSDBase)
...
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel;
AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override;
...
end;
procedure TIdStackWindows.GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer);
begin
...
end;
TIdStack.GetSocketOption()
が宣言されているかどうかに関係overload
なく、XE2 は次のエラーを報告します。
[DCC Error] IdStackWindows.pas(296): E2137 Method 'GetSocketOption' not found in base class
overload
状況によっては (Indy のように) 、派生クラスがそれをオーバーライド + オーバーロードするために、コンパイラは (基本クラス自体に対応するオーバーロードされたメソッドがなくても) 基本クラスのメソッドを as として宣言する必要があることが判明しました。
ただし、それを行った場合、XE2 以前では機能せず、「仮想メソッドを非表示にします」という警告やその他のエラーが発生しました。これは XE3 で修正されたようです。だから私がインディでしなければならなかったことは次のとおりでした:
TIdStack
基本メソッドを として宣言しoverload; virtual; abstract;
ます。
でTIdStackBDSBase
、オーバーライドされたメソッドを として宣言し、次のようにしますoverload; override;
。
a. XE2 以前では、オーバーロードされたメソッドを として宣言し、の子孫に対してreintroduce; overload;
オーバーロードされていない別のメソッドを宣言します。virtual; abstract;
override
b. XE3 以降では、オーバーロードされたメソッドを として宣言し、overload; virtual; abstract;
子孫override
にそれらを正常にさせます。
つまり、次のコードは XE3 では機能しますが、XE2 では機能しません。
type
TIdStack = class(TObject)
...
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer); overload; virtual; abstract;
...
end;
.
type
TIdStackBSDBase = class(TIdStack)
...
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer); overload; override;
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); overload; virtual; abstract;
...
end;
procedure TIdStackBSDBase.GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer);
var
LBuf, LLen: Integer;
begin
LLen := SizeOf(LBuf);
GetSocketOption(ASocket, ALevel, AOptName, LBuf, LLen);
AOptVal := LBuf;
end;
.
type
TIdStackWindows = class(TIdStackBSDBase)
...
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override;
...
end;
procedure TIdStackWindows.GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer);
begin
...
end;
ただし、次のコードは XE2 で機能します。
type
TIdStack = class(TObject)
...
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer); overload; virtual; abstract;
...
end;
.
type
TIdStackBSDBase = class(TIdStack)
...
procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); virtual; abstract;
...
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer); overload; override;
procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); reintroduce; overload;
...
end;
procedure TIdStackBSDBase.GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer);
var
LBuf, LLen: Integer;
begin
LLen := SizeOf(LBuf);
WSGetSocketOption(ASocket, ALevel, AOptName, LBuf, LLen);
AOptVal := LBuf;
end;
procedure TIdStackBSDBase.GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer);
begin
WSGetSocketOption(ASocket, ALevel, AOptName, AOptVal, AOptLen);
end;
.
type
TIdStackWindows = class(TIdStackBSDBase)
...
procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override;
...
end;
procedure TIdStackWindows.WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer);
begin
...
end;