Board index » delphi » Linked list Class (Delphi Unleashed)

Linked list Class (Delphi Unleashed)

I would like to create a linked list class.  "Delphi Unleashed" has an
example of a linked list record in chapter 16.  I compile and run the
example just fine.  I change the word "record" to "object" and it still
compiles and runs just fine.  But when I change the word "record" to
"class" it gets a protection violation.  Why?  How can I make a linked
list of classes?

--
--------------------------------------------------------------------
Rick Amerson            amer...@hpl.hp.com
1501 Page Mill Rd.      (415) 857-8080  
Palo Alto, Ca. 94303    fax (415) 813-3381

 

Re:Linked list Class (Delphi Unleashed)


In article <3sr2am$...@mips.arb-phys.uni-dortmund.de>,

Quote
marc hoffmann <m...@arb-phys.uni-dortmund.de> wrote:

>the thing is, the the new "class" objects are automatically allocated on the heap, and TListObject is already a
>POINTER to the real objects, whils with normal objects you would greate them expicitly on the heap with New, and use
>a pListObject type as pointer.

>this also the reason why you HAVE to call the constrcutor/destructor for the class when allocating/freeing it, while
>with old objects you did not have to do this, as long as they did not contain virtual methods.

Thank you for your response.  The problem is definitely connected with the
difference in the way objects and classes are handled.  When I step through with
the integrated de{*word*81}, it says the address is CSeg:xxxx.  Why would the addresses
be in the code segment?

The second instance does not seem to get a fresh object, but often overwrites the
previous instance.  Maybe the compiler is trying to help me out by destroying the
old instance?  Inside a loop, I have:

   MyObj.next := TListObject.Create;
   MyObj := MyObj.next;

where MyObj is reused on each iteration of the loop.  Stepping through shows everything
fine the first time, but the "pointer" seems to be wrong the second time.

Maybe the compiler is being too helpful by shielding me from the fact that the
object is in the heap with a pointer to it.  What is the meaning of the following?

MyObj               {a (hidden) pointer to the true object in the heap}
@MyObj              {the address in the heap, or...
                     the address of the pointer to the heap??
                     if the former, how do I get the latter?
                     if the latter, how do I get the former?}
MyObj^              {No meaning; MyObj is not a pointer}
PMyObj              {A pointer of type PListObject, by definition, but...
                     what value is in PMyObj?  Is it the same value stored
                     in MyObj, which then points to the heap, or is it
                     a pointer to MyObj which must then be dereferenced?}
PMyObj^             {Presumably the same meaning as MyObj, but ...
                     How many times is it dereferenced to get to the class object?}
@PMyObj             {The location of the pointer to ...???}

The above are straightforward ;-) for normal pointers, but for classes perhaps a
bit more obtuse.  Maybe Borland thought pointers were getting too simple so that
the average layperson could understand them.  

--
--------------------------------------------------------------------
Rick Amerson            amer...@hpl.hp.com
1501 Page Mill Rd.      (415) 857-8080  
Palo Alto, Ca. 94303    fax (415) 813-3381

Re:Linked list Class (Delphi Unleashed)


In article <DAwErp...@hpl.hp.com>, amer...@hpl.hp.com says...

Quote

>In article <3sr2am$...@mips.arb-phys.uni-dortmund.de>,
>Thank you for your response.  The problem is definitely connected with the
>difference in the way objects and classes are handled.  When I step through with
>the integrated de{*word*81}, it says the address is CSeg:xxxx.  Why would the addresses
>be in the code segment?

>The second instance does not seem to get a fresh object, but often overwrites the
>previous instance.  Maybe the compiler is trying to help me out by destroying the
>old instance?  Inside a loop, I have:

>   MyObj.next := TListObject.Create;
>   MyObj := MyObj.next;

by this, you are creating a self referenced listitem. (i.e. MyObject is equal to MyObject.Next).
try

    MyObj := TListObject.Create;
    MyObj.Next := ObList;
    ObList := MyObject

where ObList is a (global?) pointer that keeps the begining of the list. new objects are added at the beginning.
if you need to add objects at the end, use

    if ObList = nil then begin
      ObList := TListObject.Create;  
      ObList.Next := nil;               {should be nil anyways, after Create, but i with normal records you#d have
                                         to use this, so i'll leave it in}
      Last := ObList;  
    end
    else
      Last.Next := TListObject.Create;
      Last.Next.Next := nil;            {ditto}
    end;

where Last is an additional pointer (pointer being a TListObject of course) that can be discarded afterwards (but not
Free'd!!!), and ObList is the List, again.
if your list already contains objects before entering the loop, you#d have to set Last to point to that Last Object ion
the list, otherwise it would not matter:

  if ObList <> nil then begin
    Last := ObList;
    while Last.Next <> nil do Last := Last.Next;
  end;

  while {some condition} do begin
    if ObList = nil then begin
      ObList := TListObject.Create;  
      ObList.Next := nil;               {should be nil anyways, after Create, but i with normal records you#d have
                                         to use this, so i'll leave it in}
      Last := ObList;  
    end
    else
      Last.Next := TListObject.Create;
      Last.Next.Next := nil;            {ditto}
    end;
  end;

Quote
>Maybe the compiler is being too helpful by shielding me from the fact that the
>object is in the heap with a pointer to it.  What is the meaning of the following?

>MyObj               {a (hidden) pointer to the true object in the heap}

correct

Quote
>@MyObj              {the address in the heap, or...
>                     the address of the pointer to the heap??      
>                     if the former, how do I get the latter?
>                     if the latter, how do I get the former?}

the latter. the address of the pointer in the data or stack segment, depending if it's a global or local variable.
you get the former by simply accessing MyObj.

Quote
>MyObj^              {No meaning; MyObj is not a pointer}

right. MyObj^ should be the actual object on the heap, but there is nothing you can do with it (except maybe if you
would want to do such gross things as passing this as a var parameter to functions like blockwrite or such. shouln't do
that, though.

Quote
>PMyObj              {A pointer of type PListObject, by definition, but...
>                     what value is in PMyObj?  Is it the same value stored
>                     in MyObj, which then points to the heap, or is it
>                     a pointer to MyObj which must then be dereferenced?}

you would not need this anymore (you did for old style objects), since MyObject already is a pointer. PMyObj would be
the same as @MyObj.

Quote
>PMyObj^             {Presumably the same meaning as MyObj, but ...

correct

Quote
>@PMyObj             {The location of the pointer to ...???}

the pointer to the pointer to the pointer to the space on the heap
(@PMyObj -> PMyObj -> MyObj -> heap)

Quote
>The above are straightforward ;-) for normal pointers, but for classes perhaps a
>bit more obtuse.  Maybe Borland thought pointers were getting too simple so that
>the average layperson could understand them.  

well. it's not that hard really. just imagine there's a ^ behind every Txxxx
(so TForm.Height is actually (TForm^.height).

if Borland would have used this syntax, it would have looked more straiged, on the first look. but then what about
class procedures? you can call TObject.Create, even though TObject itself does not rererence a space on the heap.
so it's not just black and white, really...

anyways...
hope i could help

marc

Other Threads