delphi - Why does the compiler warn when overloading an abstract method introduced in the base class? -
i have code this:
tbaseclass = class(tobject) protected procedure amethod(const s:string);virtual;abstract; end; tderivedclass = class(tbaseclass) protected procedure amethod(const s:string);overload;override; procedure amethod(const s:string;const x:integer);overload; end;
compiler generates warning:
[dcc warning].... w1010 method 'amethod' hides virtual method of base type 'tbaseclass'
clicking on warning sends me 'amethod(const s:string;const x:integer);' since not marked override directive. however, method cannot marked override: no method signature exists in base class, , adding override directive method causes compiler error:
[dcc error].... e2037 declaration of 'amethod' differs previous declaration.
this obvious, since no method signature exists in tbaseclass.
only 'amethod(const s:string)' exists in base class, , method marked 'override' - so nothing in base class being hidden @ all.
why not erroneous warning? (not first 1 i've come across, either...)
the reference other question incorrect, imo. i have solution - used refactor, , renamed problematic method. but i'm not looking solution, trivial. i'm looking explanation of warning. there wrong design? (perhaps using overload , override not design - can agree that, that's not compiler warning about.)
i ran same problem in indy. tidstack
base class has abstract getsocketoption()
, setsocketoption()
methods tidstackbdsbase
override , overload own abstract methods descendants (tidstackwindows
, etc) override. getting these same kinds of compiler errors.
for example:
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;
regardless of whether tidstack.getsocketoption()
declared overload
or not, xe2 reports error:
[dcc error] idstackwindows.pas(296): e2137 method 'getsocketoption' not found in base class
it turns out in situations (like indy's), compiler requires base class method declared overload
(even if there no corresponding overloaded method in base class itself) in order derived class override + overload it.
however, when did that, did not work in xe2 , earlier, causing "hides virtual method" warnings , other errors. appears have been fixed in xe3. ended having in indy was:
declare base
tidstack
methodsoverload; virtual; abstract;
.in
tidstackbdsbase
, declare overriden methodsoverload; override;
, then:a. in xe2 , earlier, declare overloaded methods
reintroduce; overload;
, , declare separate non-overloadedvirtual; abstract;
methods descendantsoverride
.b. in xe3 , later, declare overloaded methods
overload; virtual; abstract;
, , let descendantsoverride
them normally.
in other words, following code works in xe3 not in 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;
the following code works in xe2, though:
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;
Comments
Post a Comment