On Thu, 3 Jul 1997 01:13:18 +0200 Frank Heckenbach heckenb@mi.uni-erlangen.de wrote:
The African Chief wrote:
[...]
- [a] a Class instance becomes a pointer to the class; (or is it that the Class itself is a pointer to an object/class?);
I think the latter would be a more consistent interpretation (at least for us, even if Delphi does it otherwise). So "class" = "pointer to object", approximately...
I agree. I think this is how Delphi does it too. "Procedure Foo (Bar: TObject)" in Delphi is the same as "Procedure Foo (Bar: pObject)" in BP. However, Delphi automatically deferences "Bar" every time it is referred to.
e.g., "Var Foo : MyFoo" = "Var Foo : ^MyFoo" in the current OOP model
Saves declaring those "PFoo" types, OTOH makes it impossible to declare global or local objects variables (without the overhead of allocating memory). If we have objects and classes, the programmer can choose what (s)he prefers.
Delphi also supports both Objects and Classes - so it would be nice if we could as well.
[b] the constructor does the heap allocation stuff, e.g., "Foo := MyFoo.Create" *allocates memory for Foo "(New, Foo)" *calls Foo^.Create (constructor)
So it's the same as "Foo := New(MyFoo, Create)" in BP?
More or less.
What about destructors? Does Delphi still use "Dispose", or has it another syntax too, or does it dispose of objects automatically.
According to the docs, the destructor destroys the object and releases the memory allocated to it. You are advised that you seldom need to call the destructor directly, and that you should call the "Free" procedure instead, to release memory and dispose of the object. It says that "Free" checks to see if the pointer is nil before calling Destroy and is also more efficient in code size.
However, when you look at the code for TObject.Destroy, it actually does nothing. Same thing with the constructor (TObject.Create). Thus all the memory allocation and deallocation stuff seems to be done with compiler magic. TObject.Free contains ASM code which tests what is in EAX (I am talking about 32-bit Delphi here), and does some other stuff with EAX and ECX and then does something with the VMT which I assume is a call to the ECX. "Destroy" destructor. Those of you who know Intel asm, will probably understand all this.
(C++, BTW, does the latter. It destroys e.g. local objects at the end of the function automatically.
Delphi destroys all objects that it creates itself. However, if you manually create an object by calling its constructor, you have to destroy it yourself with a call to "Free".
This is possible because in C++ every class has exactly one destructor. I guess they set the pointer to nil automatically at the beginning (and set it back to nil if the destructor is called manually), so they can easily find all local objects that "exist" and destroy them.)
I suspect that Delphi sets them to Nil as well, both before construction and after destruction - otherwise the checks for "Nil" made by TObject.Free would not make any sense, since there is nowhere in the source code where these things are manually set to Nil.
*Foo now points to whatever "Foo.Create" - should generate an exception because Foo needs to be assigned to the constructor
AFAICS, calling a second constructor does not even have to be forbidden -- at least in gpc. Constructors can be called like normal methods from an initialized object, though this is certainly uncommon practice.
Probably so. However, Classes are different from "mere" objects, and I suspect that with Delphi, (assuming that Foo is an instance of a Class, and not of a mere object) if you do;
New(Foo); Foo.Create;
What "Foo" is pointing to may actually be undefined - and you will certainly get an exception when you try to do anything with "Foo".
That may be why you need to assign "Foo" to its constructor - viz; Foo := TMyFoo.Create;
- Virtual methods to be overridden must be overriden
with the "override" directive; the "virtual" directive merely creates a new method (or at least, don't reject the "override" directive in a "Class" definition)
Does this mean you have to use "virtual" for *every* method in Delphi, or what is meant by "create a new method"?
Somebody else (Marius Gedminas) has responded to this.
- Allow "Published" methods (or at least, don't reject the
"published" directive in a "Class" definition).
Is this the same as "public" in C++ (= visible to everyone)? I, personally, would prefer "public", "protected" (=visible only to descendants) and "private" (=visible only to the type/class itself -- BTW, BP does it a bit differently, and extend the visibility of private methods to the whole unit it's declared in. I don't see any reason or advantage of this). So, perhaps we could allow all those keywords, including "published", in any order, also possibly repeated (unlike BP).
And this too.
- All classes to have the same ultimate ancestor object.
The same discussion as with objects recently... ;-)
Yes ;)
Is this really necessary (if so, for what?), or is it sufficient if all classes in a given library use the same ancestor by convention?
In this case, it *is* necessary for Delphi compatibility. In Delphi all classes are descendants of TObject. Doing this in Delphi;
Type MyFoo = Class end;
is exactly the same as doing this;
Type MyFoo = Class(TObject) end;
The VCL depends on this being so, and we should also support it (not least because Delphi programmers expect this to be so). This means of course that TObject then has to become part of the GPC RTS. For present purposes, it only needs to be something like this;
Type TObject = Class Constructor Create; virtual; Destructor Destroy; virtual; Procedure Free; virtual; end; {I am not sure about the "virtual" bit}
{and any other (private) stuff needed for any compiler magic that we need to do; Delphi contains some more stuff in TObject - most of them are all ASM, and I don't have a clue as to what they do }.
Like I said, "Create" and "Destroy" are empty in TObject (i.e., they contain just an empty "begin end;" block). "Free" checks whether the pointer is Nil, and if it is not, it calls Destroy. So, TObject itself is easy to implement - but I don't know what compiler magic will need to be done to make sure that everything else works as expected.
Best regards, The Chief Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant) Author of: Chief's Installer Pro v3.60 for Win16 and Win32. Homepage: http://ourworld.compuserve.com/homepages/African_Chief/ E-mail: laa12@cc.keele.ac.uk