home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.pascal
- Path: sparky!uunet!cs.utexas.edu!uwm.edu!linac!att!news.cs.indiana.edu!noose.ecn.purdue.edu!mentor.cc.purdue.edu!biomac1q.bio.purdue.edu!user
- From: pf@bilbo.bio.purdue.edu (Paul Furbacher)
- Subject: Re: Questions about Constructors and pointers to objects in TP 6
- Message-ID: <pf-230193014641@biomac1q.bio.purdue.edu>
- Followup-To: comp.lang.pascal
- Sender: news@mentor.cc.purdue.edu (USENET News)
- Organization: Purdue University
- References: <1993Jan22.171839.4925@cs.wm.edu>
- Date: Sat, 23 Jan 1993 07:34:59 GMT
- Lines: 140
-
- Where do we start and how can we be gentle with the following?
-
- In article <1993Jan22.171839.4925@cs.wm.edu>,
- greg@ms.cs.wm.edu (Gregory S. Miller) wrote:
- >
- > Is it legal for the constructor for an object to call the
- > constructor for a parent object?
-
- As they say on TV (the tube, not the framework), "Read the book."
- Essentially, it says, yes. If you have any of the source code
- which comes with TP6.0 or BP7.0, read that also. You'll see
- many examples of this. Precisely, this is what inheritance is
- all about, choosing to talk to your parents or not. If you choose
- to converse with the ancestors, the question becomes *when*.
-
- > I am having some difficulty with virtual method calls going to the wrong
- > class method, and was wondering if I might be accidentally overwriting
- > the pointer to the VMT by calling the parent class constructor from within
- > the descendant class constructor.
- >
- > A pointer of type pClass is assignment-compatible with ALL descendants of
- > Class, correct?
-
- Correct, with the appropriate typecasting. But you can get
- into trouble with this. By typecasting, you're trying
- to fake out the type-checking mechanisms built into the compiler,
- and type-checking is one of the reasons you program in Pascal
- and not something like C or BASIC.
-
- > As a result, the following should work:
- >
- > New(pDescendantPtr,Init(Stuff));
- ^ ^^^
- redundant: the "P" at the beginning means "ptr"!
-
- You've got to sit down with your manual, read it and, I'm sorry to
- say, comprehend it. After that try the following:
-
- MyDescendent := New(PDescendent, Init(...)); {ellipsis, not "Stuff"}
-
- > pClassPtr := pDescendantPtr;
-
- No, no, no. Assuming you are following naming conventions (it's
- apparent that you are not) you are trying to assign types and
- not variables. Again, look at the redundancy in your naming.
- (To re-iterate and paraphrase what S.A. Modena said yesterday in
- another thread, "pay attention to naming; it will save you
- tons of grief".)
-
- > pClassPtr^.VirtualMethod; { executes Descendant.VirtualMethod, right? }
- >
- >
- > Would this still work?
- >
- > var
- > Ptr : Pointer;
- > Classptr: pClass;
- > Descend : pDescendant;
- >
- > Classptr := Descend;
- > Ptr := Classptr;
- > pClass(Ptr)^.Virtualmethod; { still execute Descendant.VirtualMethod? }
- >
- > In my code, which I will not post yet, ...
-
- Well, much of the trouble for us in these snippets is
- that we don't know if you've done many of the things needed
- to make any of this code work.
-
- 1. Unless you have made a correct call to "New(...)" you haven't a
- chance of this working. Remember, you are working with pointers.
- This is very different from declaring "A : TClass;". The latter
- forces the compiler to allocate the static memory for "A".
- When you use pointers, the compiler only puts aside sizeof(pointer)
- for the dynamic variable. You are responsible for allocating
- the proper amount of memory for that dynamic (pointer) variable.
- Therefore, you must call "New(...)". Read about the extension
- to the "New()" function in relation to objects.
-
- 2. Once you follow an example from the source code provided
- with TP/BP, you'll be able to test some of these ideas.
- You already have the notion that you can typecast -- that's good.
-
- You can try the following:
-
- type
- PBase = ^TBase;
- TBase = object
- constructor Init(...);
- destructor Done; virtual;
- function IsA: string; virtual;
- end;
-
- PDerived = ^TDerived;
- TDerived = object
- constructor Init(...); { if necessary }
- destructor Done; virtual; { if necessary }
- function IsA: string; virtual;
- end;
- ...
- { provide method *definitions* -- learn }
- { the lingo -- such as ... }
-
- function TBase.IsA: string;
- begin
- IsA := " is an instance of TBase.";
- end;
-
- function TDerived.IsA: string;
- begin
- IsA := " is an instance of TDerived.";
- end;
- ...
-
- var
- aBase : PBase;
- aDerived : PDerived;
-
- begin
- aBase := New(PBase, Init(...));
- Writeln("aBase", aBase^.IsA);
-
- aBase := New(PDerived, Init(...));
- Writeln("aBase", aBase^.IsA);
-
- { try extending this by trying different }
- { typecasts and with the variable }
- { "aDerived" -- see what happens. }
-
- { properly dispose of the instance(s) }
- Dispose(aBase, Done);
-
- end.
-
-
- Others may have more to say on this, and some may castigate
- me for being too harsh. C'est la vie.
-
- Paul Furbacher
- pf@bilbo.bio.purdue.edu
-