Board index » delphi » Problems passing pointers/objects

Problems passing pointers/objects

I have a program I'm writing for school that, among other things, performs the following tasks:

 Defines a Person object that has a name (string) and an ID (integer).
 Defines a Student object which inherits from Person and adds a GPA property (real).
 Stores the objects in a doubly linked list, sorted by increasing order of ID.

I feed the program an input file which contains a list of commands and parameters.  One of the commands is
to insert a new object, and the object type is determined by the GPA -- if it's zero, instantiate a Person object,
otherwise instantiate a Student object.

The problem I'm encountering is that my program seems to be instantiating a Person object in all cases, even
when I tell it to instantiate a Student object.  I have asked the class TA's about it, and they couldn't figure out
what was wrong.

If anybody has some insight that would help me resolve my problem, I would greatly appreciate the
feedback.

Following are the relevant pieces of code from my program and corresponding unit, which I have modeled
somewhat after the WORKERS.PAS and WORKLIST.PAS files provided with Borland Turbo Pascal 7.0.

===========================
Unit Linked_L;
{ Contains usefull functions for manipulating objects and a linked list
  containing objects. }

INTERFACE

Type
    PPerson = ^TPerson;
    TPerson = object
            Name: string;
            ID: integer;
            constructor Init(AName: String; AnID: Integer);
            destructor Done; virtual;
            function GetName: String;
            function GetID: Integer;
            procedure Show; virtual;
    end;

    PStudent = ^TStudent;
    TStudent = object(TPerson)
            GPA: real;
            constructor Init(AName: String; AnID: Integer; AGPA: Real);
            function GetGPA: Real;
    end;

    PNode = ^TNode;
    TNode = record
          Item: PPerson;    { Could this line be my problem? }
          Next: PNode;
          Prev: PNode;
    end;

    PPeopleList = ^TPeopleList;
    TPeopleList = object
                Head, Current: PNode;
                size: integer;
                constructor Init;
                destructor Done; virtual;
                procedure Insert(Item: PPerson);
                { Requires: The linked list is not full.
                  Result:   Search for a node that contains ID.  If ID already
                            exists, the user is notified of this and no new node
                            is added.  Otherwise, a new node is added to the
                            linked list in its proper order of increasing ID
                            number.  If GPA is 0 (zero) a Person object is
                            established as the new component.  Otherwise, a Student
                            object is established as the new component. }
                procedure Display;
                end;

IMPLEMENTATION

{ TPerson }
constructor TPerson.Init(AName: String; AnID: Integer);
begin
  Name := AName;
  ID := AnID;
end;

destructor TPerson.Done;
begin
end;

function TPerson.GetName: String;
begin
  GetName := Name;
end;

function TPerson.GetID: Integer;
begin
  GetID := ID;
end;

{ TStudent }
constructor TStudent.Init(AName: String; AnID: Integer; AGPA: Real);
begin
  TPerson.Init(AName, AnID);
  GPA := AGPA;
end;

function TStudent.GetGPA: Real;
begin
  GetGPA := GPA;
end;

{ TPeopleList }
constructor TPeopleList.Init;
begin
     Head := nil;
end;

procedure TPeopleList.Insert(Item: PPerson);
var
   N: PNode;
   query: integer;
   found: boolean;
begin
     query := Item^.GetID;
     FindKey(Self, query, found);
     If found then
        writeln('The individual with ID "', Item^.ID, ' already exists.')
     Else begin
         New(N);
         N^.Item := Item;
         If (size = 0) OR (Item^.ID < Head^.Item^.ID) then begin
            N^.Next := Head;
            Head := N;
         end
         else begin
              N^.Next := Current^.Next;
              N^.Prev := Current;
              N^.Next^.Prev := N;
              N^.Prev^.Next := N;
         end;
         Current := N;
         Inc(size);
     end
end;

Begin
End.

---------------------------------------------------

Program Linked_Lists;

Uses Linked_L;

var
   People: TPeopleList;
   datafile : text;
   instruction : char;
   idbyte: integer;
   info: string;
   value: real;

Begin
  { Create an empty list }
  People.Init;

  assign(datafile, paramstr(1)); { Begin reading data from input file }
  reset(datafile);
  while not eof (datafile) do
        begin
             readln(datafile, instruction);
             case instruction of
                     'i':     { insert an object }
                              begin
                                   readln(datafile, idbyte);
                                   readln(datafile, info);
                                   readln(datafile, value);
                                   if value <> 0 then
                                      People.Insert(New(PStudent, Init(info, idbyte, value)))
                                   else
                                       People.Insert(New(PPerson, Init(info, idbyte)))
                              end;

                     's':     { show contents of an object }
                              begin
                                   readln(datafile, idbyte);
                                   ShowObject(People, idbyte);
                              end;

                     'l':     { display the entire list in order of ID }
                              begin
                                   People.Display;
                              end;

                     'e':     { erase an object/node }
                              begin
                                   readln(datafile, idbyte);
                                   EraseNode(People, idbyte);
                              end;

                     'd':     { dispose of the entire list }
                              begin
                                   People.Done;
                              end;
             end  { case }
        end;
  close(datafile);
end.

 

Re:Problems passing pointers/objects


I have a program I'm writing for school that, among other things, performs the following tasks:

 Defines a Person object that has a name (string) and an ID (integer).
 Defines a Student object which inherits from Person and adds a GPA property (real).
 Stores the objects in a doubly linked list, sorted by increasing order of ID.

I feed the program an input file which contains a list of commands and parameters.  One of the commands is
to insert a new object, and the object type is determined by the GPA -- if it's zero, instantiate a Person object,
otherwise instantiate a Student object.

The problem I'm encountering is that my program seems to be instantiating a Person object in all cases, even
when I tell it to instantiate a Student object.  I have asked the class TA's about it, and they couldn't figure out
what was wrong.

If anybody has some insight that would help me resolve my problem, I would greatly appreciate the
feedback.

Following are the relevant pieces of code from my program and corresponding unit, which I have modeled
somewhat after the WORKERS.PAS and WORKLIST.PAS files provided with Borland Turbo Pascal 7.0.

===========================
Unit Linked_L;
{ Contains usefull functions for manipulating objects and a linked list
  containing objects. }

INTERFACE

Type
    PPerson = ^TPerson;
    TPerson = object
            Name: string;
            ID: integer;
            constructor Init(AName: String; AnID: Integer);
            destructor Done; virtual;
            function GetName: String;
            function GetID: Integer;
            procedure Show; virtual;
    end;

    PStudent = ^TStudent;
    TStudent = object(TPerson)
            GPA: real;
            constructor Init(AName: String; AnID: Integer; AGPA: Real);
            function GetGPA: Real;
    end;

    PNode = ^TNode;
    TNode = record
          Item: PPerson;    { Could this line be my problem? }
          Next: PNode;
          Prev: PNode;
    end;

    PPeopleList = ^TPeopleList;
    TPeopleList = object
                Head, Current: PNode;
                size: integer;
                constructor Init;
                destructor Done; virtual;
                procedure Insert(Item: PPerson);
                { Requires: The linked list is not full.
                  Result:   Search for a node that contains ID.  If ID already
                            exists, the user is notified of this and no new node
                            is added.  Otherwise, a new node is added to the
                            linked list in its proper order of increasing ID
                            number.  If GPA is 0 (zero) a Person object is
                            established as the new component.  Otherwise, a Student
                            object is established as the new component. }
                procedure Display;
                end;

IMPLEMENTATION

{ TPerson }
constructor TPerson.Init(AName: String; AnID: Integer);
begin
  Name := AName;
  ID := AnID;
end;

destructor TPerson.Done;
begin
end;

function TPerson.GetName: String;
begin
  GetName := Name;
end;

function TPerson.GetID: Integer;
begin
  GetID := ID;
end;

{ TStudent }
constructor TStudent.Init(AName: String; AnID: Integer; AGPA: Real);
begin
  TPerson.Init(AName, AnID);
  GPA := AGPA;
end;

function TStudent.GetGPA: Real;
begin
  GetGPA := GPA;
end;

{ TPeopleList }
constructor TPeopleList.Init;
begin
     Head := nil;
end;

procedure TPeopleList.Insert(Item: PPerson);
var
   N: PNode;
   query: integer;
   found: boolean;
begin
     query := Item^.GetID;
     FindKey(Self, query, found);
     If found then
        writeln('The individual with ID "', Item^.ID, ' already exists.')
     Else begin
         New(N);
         N^.Item := Item;
         If (size = 0) OR (Item^.ID < Head^.Item^.ID) then begin
            N^.Next := Head;
            Head := N;
         end
         else begin
              N^.Next := Current^.Next;
              N^.Prev := Current;
              N^.Next^.Prev := N;
              N^.Prev^.Next := N;
         end;
         Current := N;
         Inc(size);
     end
end;

Begin
End.

---------------------------------------------------

Program Linked_Lists;

Uses Linked_L;

var
   People: TPeopleList;
   datafile : text;
   instruction : char;
   idbyte: integer;
   info: string;
   value: real;

Begin
  { Create an empty list }
  People.Init;

  assign(datafile, paramstr(1)); { Begin reading data from input file }
  reset(datafile);
  while not eof (datafile) do
        begin
             readln(datafile, instruction);
             case instruction of
                     'i':     { insert an object }
                              begin
                                   readln(datafile, idbyte);
                                   readln(datafile, info);
                                   readln(datafile, value);
                                   if value <> 0 then
                                      People.Insert(New(PStudent, Init(info, idbyte, value)))
                                   else
                                       People.Insert(New(PPerson, Init(info, idbyte)))
                              end;

                     's':     { show contents of an object }
                              begin
                                   readln(datafile, idbyte);
                                   ShowObject(People, idbyte);
                              end;

                     'l':     { display the entire list in order of ID }
                              begin
                                   People.Display;
                              end;

                     'e':     { erase an object/node }
                              begin
                                   readln(datafile, idbyte);
                                   EraseNode(People, idbyte);
                              end;

                     'd':     { dispose of the entire list }
                              begin
                                   People.Done;
                              end;
             end  { case }
        end;
  close(datafile);
end.

Re:Problems passing pointers/objects


Quote
> I have a program I'm writing for school that, among other things, performs the following tasks:

I've had some problems with those things too. I'm not sure this
will help but try the following;

 When passing an object to something you've got to pass it as
 a pointer and you shall never initialize it inside the component
 that received the object. It must be initialized before.

 Don't mess around with constructor calls inside your own object.
 They could override your VMTs for the polymorphic ancestor.

Hope it'll help you some.

/J

PS. Also check out EFLIB at http://www.ts.umu.se/~jola/EFLIB/ DS.

Other Threads