Suppose in Delphi you have these classes:
type
TClass1 = class
public
constructor Create;
end;
TClass2 = class(TClass1)
public
constructor Create;
end;
TClass3 = class(TClass2)
public
constructor Create;
end;
Note that TClass1.Create is not virtual, and that TClass2 and TClass3 declare a constructor which is not virtual.
Suppose that I want to invoke TClass1's Create constructor-method, from within TClass3.Create, but not invoke the constructor-code in TClass2.Create? Is this possible within the language without recourse to RTTI?
I don't think there is such a syntax, but what I want is:
constructor TClass3.Create;
begin
super inherited Create; // Invoke TClass1.Create
end;
The closest I can get is this which compiles but just leaks an object, as it's doing a separate TClass1.Create construction.
constructor TClass3.Create;
begin
TClass1.Create; // returns new TClass1, discards and leaks it.
// other initialization here.
end;
It also seems to me that the code TClass1.Create invocation within TClass3.Create compiles, I cannot call it correct, it is wrong because it leaks an object. What is the correct right way to do it?
Update Note that David's answer works for a class hiearchy without virtual constructors, only, as I originally asked. His answer would not work in your code, if you had virtual constructors and TClass2 and TClass3 overrode them. If I had asked the above question with virtual constructors (or a virtual method that is not a constructor) the answer would be "you can't do it at all, except by really gross Virtual Method Table hacks". Also note that the linked "possible duplicate" is not a duplicate because the answer changes when you add/subtract virtual methods from the situation.
There is no syntactical support for skipping a layer of the inheritance hierarchy. The only way you can do what you want is like this:
TClass1(Self).Create;
A complete example program to demonstrate:
type
TClass1 = class
constructor Create;
end;
TClass2 = class(TClass1)
constructor Create;
end;
TClass3 = class(TClass2)
constructor Create;
end;
constructor TClass1.Create;
begin
Writeln('TClass1');
end;
constructor TClass2.Create;
begin
inherited;
Writeln('TClass2');
end;
constructor TClass3.Create;
begin
TClass1(Self).Create;
Writeln('TClass3');
end;
begin
TClass3.Create;
Readln;
end.
Output
TClass1 TClass3
While you should not do this you actually can achieve it with inline assembly code:
constructor TClass3.Create;
begin
asm
mov eax, Self
call TClass1.Create;
end;
Writeln('TClass3');
end;
But keep in mind that this is actually different from a theoretical super inherited (which would skip one inheritance level) while this just calls the said method. So if you introduce another inheritance level TClass2b between TClass2 and TClass3 it will skip that aswell.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With