1

I have a Delphi (2007) class function like this:

Class Function InitGlobal : TForm; Overload; Virtual; Abstract;

in some descendant class I try to:

Class Function InitGlobal : TDescendentForm; Overload; Override;

But Delphi complains that TDescendentForm.InitGlobal differs from the previous declaration (despite the pressence of the "Overload" directive).

I guess that function result types can not be overloaded. Which is the correct way of define such overloading if any?

I checked Function overloading by return type?, but it mentions the cons and pros of making such overloading with no mention to Delphi.

Community
  • 1
  • 1
alvaroc
  • 433
  • 5
  • 14
  • In my humble opinion, you either `overload` or `override`, but you can't do both simultaneously. An `overload` needs to have a different method signature, while an `override` indicates that the method shall replace the method of the same name from your derived type. Perhaps a more detailed code sample could help further. – Will Marcouiller Jul 14 '14 at 19:12
  • Your opinion is irrelevant, @Will. The fact is that you *can* do both simultaneously. It happens several times in the RTL and VCL. – Rob Kennedy Jul 14 '14 at 22:45
  • Thanks for the info, @RobKennedy. I have never done both simultaneously in my career, since I have always expected the overloads to be methods which only define different parameters for a given behaviour, and the overrides to be methods which only redefine the behaviour of an object. I have never happened to do both, and I would tend to think of it as a design flaw, somehow. But hey, if you say it is done multiple times in the RTL and VCL, it must be good for some reason that I simply don't need. =) – Will Marcouiller Jul 15 '14 at 11:59

1 Answers1

3

Function overloading can only be based on parameters, and not on return values. There is no way for you to have two overloads that differ only in their return value.

What's more, even if you could do that, you are attempting to use override, and change the function's signature. That is also impossible. An override must have an identical signature to the function being overridden.

What you can do is override the function, and keep the same signature. You can remove the overload directive. Then your derived function would look like this:

class function InitGlobal: TForm; override;

Now, there is nothing to stop you returning an instance of TDescendentForm. That is still a TForm. What you would be doing here is returning a more a derived type at runtime.

The implementation might look like this:

Result := TDescendentForm.Create(...);
// compile time type of Result is TForm, but that is assignment compatible
// at run time with an instance of TDescendentForm
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Sure, he can return a TDescendentForm, but the code calling InitGlobal would not know this and not be able to access the items on the TDescendentForm, unless it casts to TDescendentForm (e.g. using `as`). But if it knows about TDescendentForm anyway, the advantage of polymorphism is lost and the function doesn't have to be virtual at all. – Rudy Velthuis Jul 14 '14 at 20:30
  • @Rudy But it would be able to call any virtual methods on the instance returned. You don't necessarily need to know the type at compile time to be able to take advantage of derived class behaviour. – David Heffernan Jul 14 '14 at 20:53
  • As David stated, overloading works only for parameters signatures, not return values so the less elegant solution used, as Rudy suggested: TDescendantForm(TDescendantForm.InitGlobal ()).SomeMethodInDescendant. If overloading the result type would be accepted, the first cast could be removed resulting in clearer code – alvaroc Jul 14 '14 at 23:37
  • Do you need any more help here? – David Heffernan Jul 15 '14 at 06:10