Next: , Previous: SetLength, Up: Reference



SetType

Synopsis

     procedure SetType (var SomeObject; VMT: PObjectType);

Description

The procedure SetType explicitly assigns a value to the implicit VMT field of an object. This is normally done implicitly when a constructor is called.

You can use this to write a polymorphic I/O routine which reads an object from a file. In this case, you cannot reasonably use New to allocate the storage, but you GetMem it and initialize the object manually using SetType before calling the constructor explicitly.

The only values you should assign to an object via SetType are actual VMT pointers that were obtained via TypeOf. In particular, declaring a record like the one shown in the description of PObjectType and assigning a pointer to it to an object via SetType will usually not work because the virtual method pointers are missing.

Since SetType is a dangerous feature, it yields a warning unless {$X+} is given.

Conforming to

SetType is a GNU Pascal extension.

Example

     program SetTypeDemo;
     
     type
       BasePtr = ^BaseObj;
     
       BaseObj = object
         constructor Load;
       end;
     
       ChildObj = object (BaseObj)
         constructor Load;
       end;
     
     constructor BaseObj.Load;
     begin
     end;
     
     constructor ChildObj.Load;
     begin
     end;
     
     {$X+}
     
     { This is somewhat fragmentary code. }
     function GetObject (var InputFile: File) = Result: BasePtr;
     const
       VMTTable: array [1 .. 2] of PObjectType =
         (TypeOf (BaseObj), TypeOf (ChildObj));
     var
       Size: Cardinal;
       TypeID: Integer;
       VMT: PObjectType;
     begin
       { Read the size of the object from some file and store it in `Size'. }
       BlockRead (InputFile, Size, SizeOf (Size));
     
       { Allocate memory for the object. }
       GetMem (Result, Size);
     
       { Read some ID from some file. }
       BlockRead (InputFile, TypeID, SizeOf (TypeID));
     
       { Look up the `VMT' from some table. }
       { Explicit range checking wouldn't be a bad idea here ... }
       { Without it, a wrong value just leads to a runtime error. }
       VMT := VMTTable[TypeID];
     
       SetType (Result^, VMT);
     
       { Now the object is ready, and the constructor can be called. }
       { Look up the correct constructor from some table and call it. }
     end;
     
     begin
     end.

See also

PObjectType, TypeOf, OOP.