According to The African Chief:
If you don't use "override", then it creates a new method by the same name, which replaces the original one. The full implications of this are not clear to me yet, but they have caused me some grief a few times (things not behaving as you expect).
But I think that I have understood it now. :-)
While `override' overrides a virtual method, i.e. replaces its entry in the VMT, `virtual' would create a new entry in the VMT, thus making the old method inaccessible - except when using this class through a pointer to a parent class.
One example (I hope there aren't too many typos):
Type
FooClass = class Constructor Create; Procedure Bar; virtual; end (* FooClass *);
Foo2Class = class ( FooClass ) Procedure Bar; override; end (* Foo2Class *);
Foo3Class = class ( Foo2Class ) Procedure Bar; virtual; end (* Foo3Class *);
Foo4Class = class ( Foo3Class ) Procedure Bar; override; end (* Foo4Class *);
Var Foo: FooClass; Foo2: Foo2Class; Foo3: Foo3Class; Foo4: Foo4Class;
...
Foo4:= Foo4Class.Create; Foo3:= Foo4; Foo2:= Foo4; Foo:= Foo4;
Foo4.Bar; (* calls Foo4Class.Bar *) Foo3.Bar; (* calls Foo4Class.Bar which overrides Foo3Class.Bar *) Foo2.Bar; (* calls Foo2Class.Bar *) Foo1.Bar; (* calls Foo2Class.Bar which overrides FooClass.Bar *)
That's my guess. If somebody really *knows* it, please tell me!
given this; "Procedure Foo (Bar:TObject)"
In Delphi, Bar is a pointer (even though it is automatically deferenced). In BP it is not a pointer (you would have to do "Bar: pObject", and then do some magic to dereference it automatically, to achieve the same thing).
In BP (and GPC), you have to write "Procedure Foo ( Var Bar: tObject )" to get (almost) exactly the same: `Var' parameters are internally passed through a pointer which is implicitly dereferenced whenever you access the parameter.
Sounds logical. But when does Delphi create objects by itself?
When it manages the project, e,g., when you drag objects from the repository onto your form - which is how most Delphi programs are meant to be written.
Then it's not Delphi (the compiler) who creates and destroys the objects but VCL which has this close interaction with the development tools.
Well, "Free" is written in ASM. So, maybe therein lies the magic. I don't understand the ASM code, so I can't really comment on this.
Well, as long as you know *exactly* what the compiler does, you can write and use `Free' - perhaps even as a virtual method. But I remember well a rather strange bug in one of my programs when I upgraded from TP6 to BP7 without replacing my heavily-modified Turbo Vision with the new version, and I finally discovered the following in `menus.pas' from Turbo Vision:
function NewItem(Name, Param: TMenuStr; KeyCode: Word; Command: Word; AHelpCtx: Word; Next: PMenuItem): PMenuItem; var T: PView; P: PMenuItem; begin if (Name <> '') and (Command <> 0) then begin New(P); P^.Next := Next; P^.Name := NewStr(Name); P^.Command := Command; P^.Disabled := not T^.CommandEnabled(Command); P^.KeyCode := KeyCode; P^.HelpCtx := AHelpCtx; P^.Param := NewStr(Param); NewItem := P; end else NewItem := Next; end;
Note that "T^.CommandEnabled(Command)" is called with `T' being an *uninitialized* local variable! So it was quite natural that my BP7-compiled protected-mode program barfed. But why did the same program accept it when compiled with TP6? Well, `CommandEnabled' is not a virtual method, and the body of `CommandEnabled' does never refer to any data fields of the object. (So why it's a method then???) Everything which happens with the implicit `Self' parameter then is that it is loaded into the `es:di' register pair ... which doesn't matter in real mode but causes a protection fault in protected mode if the `es' register does not get a valid selector. That's why the BP7 program crashed.
So, everybody, don't use uninitialized local variables, especially not pointers! Yes, Borland, you too!
How did Borland solve this problem in BP7?
const T: PView = nil;
... P^.Disabled := not T^.CommandEnabled(Command); ...
It's great, isn't it? Now you see why I do not want to trust Delphi and VCL and prefer to hack GPC instead ...
Greetings,
Peter
Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer peter.gerwinski@uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201] maintainer GNU Pascal [970624] - http://home.pages.de/~gnu-pascal/ [970125]