Jacek Laskowski 57 Posted April 16, 2019 I have two classes: TFoo = class procedure Terminate(aNow: Boolean); virtual; end; TBar = class(TFoo) procedure Terminate(); end; procedure TBar.Terminate(); begin inherited Terminate(True); end; but I am getting a warning when compiling: [dcc32 Warning] W1010 Method 'Terminate' hides a virtual method of base type How to correctly declare the Terminate () method? I tried with overload, but it did not help. Share this post Link to post
Dalija Prasnikar 1399 Posted April 16, 2019 54 minutes ago, Jacek Laskowski said: I tried with overload, but it did not help. http://docwiki.embarcadero.com/RADStudio/Rio/en/Methods_(Delphi) Overload is used when you have methods with same name but different parameters. Override is used when you have methods with same name and same parameters, but one is in parent class (marked as virtual or dynamic) and other is in child class and you want to override method functionality in child class. Share this post Link to post
HolgerX 7 Posted April 16, 2019 Hmm.. I thing 'override' is wrong, 'reintroduce' have to use! The declaration is different. 1 Share this post Link to post
Jacek Laskowski 57 Posted April 16, 2019 (edited) Of course, override generate other error: [dcc32 Error] E2037 Declaration of 'Terminate' differs from previous declaration Edited April 16, 2019 by Jacek Laskowski Share this post Link to post
Bill Meyer 337 Posted April 16, 2019 11 minutes ago, Jacek Laskowski said: Of course, override generate other error: [dcc32 Error] E2037 Declaration of 'Terminate' differs from previous declaration Implementing an override to a virtual method the signatures must match. Your error is not from using override, but from changing the signature. 1 Share this post Link to post
Jacek Laskowski 57 Posted April 16, 2019 3 minutes ago, Bill Meyer said: Implementing an override to a virtual method the signatures must match. Your error is not from using override, but from changing the signature. I know where a warning message comes from. I ask how to solve it correctly for the Terminate method without parameters. Share this post Link to post
David Heffernan 2352 Posted April 16, 2019 (edited) Perhaps you should step back and ask why you want two distinct things to have the same name. That, rather than the banal compilation warning, is surely the real issue here. Edited April 16, 2019 by David Heffernan Share this post Link to post
PeterBelow 239 Posted April 16, 2019 2 hours ago, Jacek Laskowski said: I have two classes: TFoo = class procedure Terminate(aNow: Boolean); virtual; end; TBar = class(TFoo) procedure Terminate(); end; procedure TBar.Terminate(); begin inherited Terminate(True); end; but I am getting a warning when compiling: [dcc32 Warning] W1010 Method 'Terminate' hides a virtual method of base type How to correctly declare the Terminate () method? The classical way to handle this is to refactor TFoo like this: TFoo = class(TObject) strict protected procedure DoTerminate(aNow: Boolean); virtual; public procedure Terminate; virtual; end; TBar = class(TObject) public procedure Terminate; override; end; procedure TFoo.Terminate; begin DoTerminate(false); end; procedure TBar.Terminate; begin DoTerminate(true); end; Share this post Link to post
Jacek Laskowski 57 Posted April 16, 2019 20 minutes ago, David Heffernan said: Perhaps you should step back and ask why toy want two distinct things to have the same name. That, rather than the banal compilation warning, is surely the real issue here. From the base class, TFoo inherits several different classes, just this one child class TBar should always pass True in this parameter. Share this post Link to post
Jacek Laskowski 57 Posted April 16, 2019 9 minutes ago, PeterBelow said: The classical way to handle this is to refactor TFoo like this: TFoo = class(TObject) strict protected procedure DoTerminate(aNow: Boolean); virtual; public procedure Terminate; virtual; end; TBar = class(TObject) public procedure Terminate; override; end; procedure TFoo.Terminate; begin DoTerminate(false); end; procedure TBar.Terminate; begin DoTerminate(true); end; Thanks, but what if another class inheriting from TFoo needs to be able to control the parameter from outside? Share this post Link to post
Remy Lebeau 1420 Posted April 16, 2019 1 hour ago, Jacek Laskowski said: I ask how to solve it correctly for the Terminate method without parameters. If you want to use the same name with different parameters, you have to declare both methods as 'overload', or else declare the TBar method as 'reintroduce', which will still hide the TFoo method. Otherwise, I would just rename the TBar method to something more meaningful: TFoo = class procedure Terminate(aNow: Boolean); virtual; end; TBar = class(TFoo) procedure TerminateNow(); end; procedure TBar.TerminateNow(); begin inherited Terminate(True); end; Share this post Link to post
Uwe Raabe 2061 Posted April 16, 2019 1 hour ago, Remy Lebeau said: If you want to use the same name with different parameters, you have to declare both methods as 'overload', or else declare the TBar method as 'reintroduce', which will still hide the TFoo method. You can as well combine both avoiding the hide effect: TBar = class(TFoo) procedure Terminate; reintroduce; overload; end; 1 Share this post Link to post
Rudy Velthuis 91 Posted April 16, 2019 (edited) 49 minutes ago, Uwe Raabe said: You can as well combine both avoiding the hide effect: TBar = class(TFoo) procedure Terminate; reintroduce; overload; end; That is actualy the documented way to do this. I wondered why it took so long before someone came up with it. OP probably comes from C++, where directives like override, reintroduce or overload are not necessary. If the signature is different, it overloads and does not hide. Edited April 16, 2019 by Rudy Velthuis Share this post Link to post
Remy Lebeau 1420 Posted April 16, 2019 2 hours ago, Rudy Velthuis said: OP probably comes from C++, where directives like override, reintroduce or overload are not necessary. If the signature is different, it overloads and does not hide. Note that C++11 addes the 'override' keyword to the language, and its use is highly recommended to discover typos at compile-time. If a derived class method wants to override a base class virtual method, an explicit 'override' allows the compiler to validate that the overriding method actually matches the signature of an available base virtual method, if not the compile fails. Without the explicit 'override', a mistyped overriding method would be an overload instead, which can lead to logic errors not detectable until run-time. 2 Share this post Link to post
Rudy Velthuis 91 Posted April 18, 2019 On 4/16/2019 at 11:37 PM, Remy Lebeau said: Note that C++11 addes the 'override' keyword to the language, and its use is highly recommended to discover typos at compile-time. If a derived class method wants to override a base class virtual method, an explicit 'override' allows the compiler to validate that the overriding method actually matches the signature of an available base virtual method, if not the compile fails. Without the explicit 'override', a mistyped overriding method would be an overload instead, which can lead to logic errors not detectable until run-time. I didn't know that, but it looks like it has the equivalent but opposite meaning of reintroduce in Delphi. Of course it is useful, in C++ too. Share this post Link to post
HolgerX 7 Posted April 18, 2019 On 4/16/2019 at 8:32 PM, Rudy Velthuis said: That is actualy the documented way to do this. I wondered why it took so long before someone came up with it. OP probably comes from C++, where directives like override, reintroduce or overload are not necessary. If the signature is different, it overloads and does not hide. Hmm.. I came with this some posts ago, but I think you didn't need overload when you use 'reintroduce'.. Share this post Link to post
Rudy Velthuis 91 Posted April 18, 2019 (edited) 29 minutes ago, HolgerX said: Hmm.. I came with this some posts ago, but I think you didn't need overload when you use 'reintroduce'.. If you use reintroduce, you hide the virtual implementation. But if you want to overload it, and leave the virtual method visible and accessible/inheritable too, you must use both reintroduce and overload, in the correct order. This is documented somewhere. Edited April 18, 2019 by Rudy Velthuis Share this post Link to post