Node: SetType, Next: shl, 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. }
           { Range checking wouldn't be a bad idea here ... }
           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.